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()?