Android Activity onCreate 方法调用的同步方法

Posted

技术标签:

【中文标题】Android Activity onCreate 方法调用的同步方法【英文标题】:Synchronized method called by Android Activity onCreate method 【发布时间】:2016-08-29 03:20:57 【问题描述】:

以下情况是糟糕的设计还是我忽略了一些重要的事情?

这里是代码

public class MainActivity extends AppCompatActivity … 

  …

  @Override
  public void onCreate(Bundle savedInstanceState)
     …
     buildGoogleApiClient();
  

  /**
   * Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
   */
    protected synchronized void buildGoogleApiClient() 
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    

为什么buildGoogleApiClient synchronized 只能从内部onCreate 调用?

我知道这不会造成伤害,但这并不是问题的重点。我需要知道的是:为什么需要?

编辑

完整代码来源:https://github.com/googlesamples/android-play-location/blob/master/BasicLocationSample/app/src/main/java/com/google/android/gms/location/sample/basiclocationsample/MainActivity.java

【问题讨论】:

感谢您的回复。但不幸的是,我不明白你的回答。谢谢。 就该方法的当前使用而言,我会说不,没有必要。事实上,我不知道为什么会有多个线程试图在一个应用上构建同一个 API 客户端。 这是来自developer.android.com/training/location/retrieve-current.html。他们的工程师应该是一流的,而且他们构建了 android,所以......值得想知道这里发生了什么。 【参考方案1】:

在这种情况下,synchronized 将在调用期间锁定对象。如果还有其他方法也声明了synchronized,那么在任何给定时间只会执行其中一个。例如,如果从另一个线程上的同步方法访问mGoogleApiClient,则同步将确保另一个线程看到完全构造的对象或空引用。

即便如此,您仍然可以证明这是一个糟糕的实现。更好的方法是让每个方法在私有对象上同步,这样类外的代码就不会无意中锁定对象并导致意外行为。 OTOH,可以说synchronized 方法作为示例更好,因为代码行更少,而且同步适用于整个方法很明显。

在这种特殊情况下,volatile 可能会起作用,但我不确定它如何与构建器模式一起发挥作用。

无论如何,您都需要了解更多关于... 代码部分的信息,以了解是否需要同步。

【讨论】:

感谢您的回复。我添加了 ... 以截断代码。来源是github.com/googlesamples/android-play-location/blob/master/…。你似乎在解释一般的并发性。但是关键字在所提供的上下文中如何应用? 我看到了一些可能性:(1)如果可以在任意线程上调用像onConnectionSuspended() 这样的回调,那么同步可能会很有用。当然,回调同步,所以不是这样。 (2) 同步方法是protected,所以也许开发者预料到它会用在同样是多线程的派生类中。 (3) 它是从其他一些实际需要的项目中复制和粘贴的。不管怎样,如果mGoogleApiClient只被一个线程访问,则不需要同步访问。

以上是关于Android Activity onCreate 方法调用的同步方法的主要内容,如果未能解决你的问题,请参考以下文章

Android Activity 中 onCreate 方法第二个实现有啥用?

Android:如果将 Activity 带回屏幕上,通知中的 PendingIntent 不会触发 onCreate()

Android Activity onCreate 方法调用的同步方法

Android 何时在 Activity.onCreate() 中的 setContentView() 之后首次调用 View.onMeasure()?

从Android Activity onCreate方法调用QCoreApplication方法

为啥fragmentactivity 不是每次都执行了oncreate