1. 程式人生 > >SharedUserId引起的Application延遲初始化

SharedUserId引起的Application延遲初始化

我們都知道應用的Application初始化一般在bindApplication的時候,但是有一種情況會導致Application建立延遲,就是shareduid的情況下,兩個程序執行在同一個程序中

拿com.android.providers.downloads 和com.android.providers.media舉例, 加入有人先呼叫media provider ,這時候經過層層呼叫到

AMS->attachApplicationLocked之後,執行

thread.bindApplication(processName, appInfo, providers, app.instrumentationClass
, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated
), mCoreSettingsObserver.getCoreSettingsLocked());

注意這裡面有兩個引數是這裡要說明的問題, 在此情景中(shareduid 先啟動media provider)appInfo 是指向com.android.providers.media的包名應用,但是providers則包含media和downloads程序

中的所有provider. 呼叫的AtivityThread 後就會進行installContentProviders. installContentProviders遍歷該程序的所有providers 使用

installProvider進行釋出
我們來看下應用端installProvider的邏輯中比較關鍵的一部分

if (context.getPackageName().equals(ai.packageName)) {
    c = context;
} else if (mInitialApplication != null &&
        mInitialApplication.getPackageName().equals(ai.packageName)) {
    c = mInitialApplication;
} else { //3
    try {
        c = context.createPackageContext(ai.packageName,
 Context.CONTEXT_INCLUDE_CODE);
 } catch (PackageManager.NameNotFoundException e) {
        // Ignore
 }
}

如果啟動的provider為com.android.providers.downloads中的provider的情況,會走到條件3.這種情況下downloadProvider 雖然執行了onCreate,但是並沒有ApplicationContext,因為它裡面能獲取到的Context
是由context.createPackageContext(ai.packageName,Context.CONTEXT_INCLUDE_CODE); 建立的,所以沒有ApplicationContext.只有當com.android.providers.downloads建立activity service receiver的時候才會進行makeApplication()建立application.

所以在provider中使用application還是要小心的