我们都知道应用的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还是要小心的