Android Application 启动流程 一文带你看懂Android Application启动流程是怎样的
冬天的毛毛雨 人气:9基于Android11-API30
总览
- 获取applicationThread,AMS这两个Binder2.attach时,将获取applicationThread对象也传递到AMS进程,请求远程调用通知AMS应用进程想要创建Application,此时AMS为服务端
- AMS收到消息,请求调用applicationThread的远程接口,此时AMS为客户端
- applicationThread收到AMS的请求,通过Handler发起创建Application的处理任务,后面就没有远程接口调用了
- 通过反射创建Application的实例,通过Instrumentation启动Application的onCreate方法
详细流程分析
从 ActivityThread.java 的main方法开始看;
public static void main(String[] args) { ... ActivityThread thread = new ActivityThread(); thread.attach(system=false, startSeq);//1 ... }
进入attach
方法;
if(!system){ final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread, startSeq);//1 } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } }
非系统应用流程,根据 getSeervice和捕获的RemoteException可以断定,此处在使用Binder进行远程接口调用。
转身看下mAppThread是什么?
final ApplicationThread mAppThread = new ApplicationThread(); private class ApplicationThread extends IApplicationThread.Stub { //批量的schedule*接口,比如scheduleReceiver、scheduleCreateService等 public final void schedule* //TODO 关键方法 public final void bindApplication(some args){}//1 //一堆dump方法,比如dumpMemory、dumpActivity等 }
可以看到,ApplicationThread是一个实现了远程接口的Binder客户端,内部封装实现了很多远程接口。不过这个客户端什么时候连接的服务器还未可知,没有找到bindService关键字,反正此时应该已经连接上对应的Service了。应该是在RuntimeInit.java类中进行应用进程启动时启动的。
回来看下前一步服务的实例IActivityManager.attachApplication()内部的实现。
先获取AMS的实例,此处获取AMS实例代码跟Activity启动流程中一致
public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
…获取到AMS的Binder后,继续查看ActivityManagerService.java中的attachApplication方法
public final void attachApplication(IApplicationThread thread, long startSeq) { synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid, callingUid, startSeq); //1 Binder.restoreCallingIdentity(origId); } }
单例获取AMS实例,AMS服务在系统启动就已经注册到ServiceManager了,此处直接去获取Binder实例就行,ServiceManager以Binder池的方式管理注册的Server。
AMS的attachApplication方法中进入到attachApplicationLocked方法,捡能看懂的代码看,跟着thread参数查看代码。
private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { try { AppDeathRecipient adr = new AppDeathRecipient( app, pid, thread); thread.asBinder().linkToDeath(adr, 0);//1 app.deathRecipient = adr; } catch (RemoteException e) { app.resetPackageList(mProcessStats); mProcessList.startProcessLocked(app, new HostingRecord("link fail", processName), ZYGOTE_POLICY_FLAG_EMPTY); return false; } final ActiveInstrumentation instr2 = app.getActiveInstrumentation(); if (instr2 != null) {//2 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.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions, app.mDisabledCompatChanges); } else { thread.bindApplication(processName, appInfo, providerList, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions, app.mDisabledCompatChanges); } }
先给ApplicationThread这个Binder上个死亡代理,根据这个死亡代理应该可以找到对应的Service是如何重新启动的,感兴趣可以继续深入,咱们继续往下走。
此处调用到thread.bindApplication接口,前面咱们查看ApplicationThread时有看到,直接切入。
private class ApplicationThread extends IApplicationThread.Stub { //批量的schedule*接口,比如scheduleReceiver、scheduleCreateService等 public final void schedule* //TODO 关键方法 public final void bindApplication(some args){ AppBindData data = new AppBindData(); ...一堆参数 sendMessage(H.BIND_APPLICATION, data);//1 } //一堆dump方法,比如dumpMemory、dumpActivity等 }
到达咱们Android开发工程师比较熟悉的点了,封装了一堆参数后,通过H这个Handler对象发了一条BIND_APPLICATION消息,咱们看看这条消息去哪了,直接跟进BIND_APPLICATION这个消息的捕捉位置。
//消息分发 class H extends Handler{ public void handleMessage(Message msg){ swich(msg.what){ case BIND_APPLICATION: AppBindData data = (AppBindData)msg.obj; handleBindApplication(data);//1 break; ...省略 } } }
进入消息分发处理方法,这个方法比较长,注意阅读能看懂的代码,不求甚解,跟踪data的处理。
private void handleBindApplication(AppBindData data) { //各种初始化,比如进程名,应用名,AsyncTask线程池的配置,时区,网络发现 //Context的初始化 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); try { final ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation)//1 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } final ComponentName component = new ComponentName(ii.packageName, ii.name); mInstrumentation.init(this, instrContext, appContext, component,//1 data.instrumentationWatcher, data.instrumentationUiAutomationConnection); ... Application app; app = data.info.makeApplication(data.restrictedBackupMode, null);//2 mInstrumentation.onCreate(data.instrumentationArgs); mInstrumentation.callApplicationOnCreate(app);//3 }
通过反射实例化mInstrumentation对象,该对象为Android系统组件的管家,目前看可以控制Application和Activity的生命周期。
创建Application对象,进去看下创建的代码
//LoadApk.java #makeApplication public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation){ ... app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);//1 appContext.setOuterContext(app); ... } //Instrumentation.java #newApplication public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Application app = getFactory(context.getPackageName()) .instantiateApplication(cl, className);//2 app.attach(context);//首先回调attachBaseContext方法 return app; } //AppComponentFactory #instantiateApplication public @NonNull Application instantiateApplication(@NonNull ClassLoader cl, @NonNull String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Application) cl.loadClass(className).newInstance();//3 }
可以看出最后还是通过反射初始化了Application。
最后通过mInstrumentation对象完成Application类的onCreate方法的调用。
mInstrumentation.callApplicationOnCreate(app);//1 //Instrumentation.java #callApplicationOnCreate public void callApplicationOnCreate(Application app) { app.onCreate(); }
加载全部内容