赞
踩
上一篇文章通过日志发现有这个循序
Application#attachBaseContext() → ContentProvider#attachInfo() → ContentProvider#onCreate() → Application#onCreate()
Android Code Search android官方在线阅读源码神器
此处分析android-12.0.0_r32源码
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
Looper.prepareMainLooper();
...
//创建ActivityThread
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
...
Looper.loop();
}
main函数中的重点是创建主线程Looper,事件循环。并创建ActivityThread来初始化程序。
final ApplicationThread mAppThread = new ApplicationThread();
private void attach(boolean system, long startSeq) {
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
private class ApplicationThread extends IApplicationThread.Stub {
}
public interface IApplicationThread extends android.os.IInterface{
// 静态内部类
public static abstract class Stub extends android.os.Binder implements android.app.IApplicationThread{
}
}
mAppThread = new ApplicationThread()非要重要,ApplicationThread属于ActivityThread的内部类,实现了IApplicationThread.Stub,也就是具备了Binder跨进程通信能力。
ActivityManager.getService方法获取ActivityManagerService简称AMS,调用了AMS的attachApplication方法,并把ApplicationThread作为参数传递过去。
AMS位于Framework层,android系统的一个系统服务,Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作。
文件路径:out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/xref26/srcjars.xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override public final void attachApplication(IApplicationThread thread, long startSeq) { attachApplicationLocked(thread, callingPid, callingUid, startSeq); } private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { List<ProviderInfo> providers = normalMode? mCpHelper.generateApplicationProvidersLocked(app): null; final ProviderInfoList providerList = ProviderInfoList.fromList(providers); //providerList是重点 thread.bindApplication(processName, appInfo, providerList, instr2.mClass, profilerInfo, instr2.mArguments, instr2.mWatcher, instr2.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()), app.getCompat(), getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions, app.getDisabledCompatChanges(), serializedSystemFontMap); }
上一步mgr.attachApplication进入framework层,在attachApplicationLocked中进行很多的操作,比如判断进程pid,是否具备拉起的条件,解析app中的用到的provider,进入ApplicationThread的bindApplication方法中。
路径:frameworks/base/core/java/android/app/ActivityThread.java
public final void bindApplication(String processName, ApplicationInfo appInfo, ProviderInfoList providerList, ComponentName instrumentationName, ...) ... //构造需要的数据 AppBindData data = new AppBindData(); //后面初始化会用到providers data.providers = providerList.getList(); data.instrumentationName = instrumentationName; //省略其他参数赋值 sendMessage(H.BIND_APPLICATION, data); } void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { mH.sendMessage(msg); }
在AMS中调用thread.bindApplication,相当于又回到了应用的ActivityThread中,最终调用了mH.sendMessage方法。mH是在ActivityThread中初始化的Handler,最终又回到了ActivityThread中。
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
Handler收到BIND_APPLICATION消息,开始执行handleBindApplication。
private void handleBindApplication(AppBindData data) { final InstrumentationInfo ii; if (data.instrumentationName != null) { ii = prepareInstrumentation(data); } else { ii = null; } //创建ContextImpl final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); if (ii != null) { //实际会走这里,在里面初始化mInstrumentation initInstrumentation(ii, data, appContext); } else { mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); } //创建Application对象,会执行attachBaseContext(context); Application app; app = data.info.makeApplication(data.restrictedBackupMode, null); // 初始化Provider installContentProviders(app, data.providers); // 执行Application的OnCreate mInstrumentation.callApplicationOnCreate(app); } // 文件路径frameworks/base/core/java/android/app/ContextImpl.java class ContextImpl extends Context { }
ContextImpl继承Context,是Context API 的通用实现,它提供了基础Activity 和其他应用程序组件的上下文对象。
Instrumentation 是一个可以在任何application执行代码之前,可以监视app和系统的交互。并且可以在AndroidManifest中配置。也由它执行执行Application的OnCreate。
// 注意这个context,是从上面传递下来的app,也就是application private void installContentProviders( Context context, List<ProviderInfo> providers) { for (ProviderInfo cpi : providers) { ContentProviderHolder cph = installProvider(context, null, cpi, false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); } } private ContentProviderHolder installProvider(Context context, ContentProviderHolder holder, ProviderInfo info, boolean noisy, boolean noReleaseNeeded, boolean stable) { ContentProvider localProvider = null; final java.lang.ClassLoader cl = c.getClassLoader(); // 通过ClassLoader 反射构建ContentProvider localProvider = packageInfo.getAppFactory().instantiateProvider(cl, info.name); // localProvider.attachInfo(c, info); }
makeApplication创建application中会执行attachBaseContext(context);
installContentProviders第一个参数context,是从上面传递下来的app,也就是application。
遍历providers列表,初始化每一个provider,都是用application的context。构造出ContentProvider然后执行attachInfo() 方法,attachInfo()执行完毕会执行onCreate()。
最后再mInstrumentation.callApplicationOnCreate(app);执行Application的OnCreate方法。
从流程上来看,符合日志打印的流程Application#attachBaseContext() → ContentProvider#attachInfo() → ContentProvider#onCreate() → Application#onCreate()
ContentProvider持有的Context也是application,具备给SDK初始化使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。