Activity启动流程
就拿最简单的启动方式,即startActivity(Intent)来看,首先是在Activity.java中:
1 |
|
调用重载的startActivity()方法,多传入一个空的bundle参数:
1 | public void startActivity(Intent intent, @Nullable Bundle options) { |
因为bunlde为null,所以走下面这个路径:
1 | public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, |
这里有个疑问,mParent是何用?在网上查阅资料后得知,这个东西是ActivityGroup的遗物,一般Activity是没有的,所以这里会走if这条路。那么可以看到启动Activity时主要在这里:
1 | Instrumentation.ActivityResult ar = |
先调用mInstrumentation的execStartActivity()方法,启动Activity,启动完毕之后然后拿到返回的启动结果作为一个ActivityRersult,有了这个result就可以做ActivityResult()。那么首先来看一下execStartActivity()方法是怎么执行的:
在Instrumentation.java类中:
1 | public ActivityResult execStartActivity( |
AMS即ActivityManagerService,这里是用过Binder机制远程调用了他。现在看ActivityManagerService.java的startActivity()方法:
1 |
|
调用了startActivityAsUser()方法:
1 |
|
在获取了一个userId之后,调用了mActivityStarter的mActivityStarter.startActivityMayWait()方法。这个mActivityStarter是一个ActivityStarter类的对象,这个类主要用来做Activity启动之前的准备工作,比如intent和flags的逻辑,管理stack和taskrecord等。接下来进入了ActivityStarter.java中:
1 | final int startActivityMayWait(IApplicationThread caller, int callingUid, |
在这面首先获取了传入的Intent等信息,之后交给startActivityLocked()方法来创建ActivityRecord,这其中就包含着Activity的重要信息。在这一方法中,层层调用之后来到了这里:
1 | private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, |
在调用startActivityUnchecked()时,最终走到了ActivityStackSupervisor.java中:
1 |
|
ActivityStackSupervisor类与ActivityStack类配合使用. ActivityStackSupervisor负责管理Task和Stack, 而ActivityStack负责管理在Stack和Task中的Activity。
这里会调用activityStack的resumeTopActivityUncheckedLocked()方法,然后开始一个调用链:
ActivityStack的resumeTopActivityInnerLocked() ->
ActivityStackSupervisor的startSpecificActivityLocked() -> ActivityStackSupervisor的realStartActivityLocked()
到这里,正如方法名所描述的那样,真正开始启动Activity了:
1 | app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, |
最后由ActivityThread中的ApplicationThread调用scheduleLaunchActivity完成Activity的真正启动。这里的thread是IApplicationThread接口,该接口继承了IInterface接口,实现方法asBinder()方法作为binder通信。
所以最终的启动就到了ActivityThrad.java中,怎么,熟不熟悉?
1 | public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, |
很显然,启动Activity是要先创建一个ActivityClientRecord对象,然后通过Handler消息机制来告诉我们的主线程来启动,直接来看H.LAUNCH_ACTIVITY这条消息的处理:
1 | case LAUNCH_ACTIVITY: { |
调用了hanlleLaunchActivity()方法用来启动Actiivity:
1 | private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { |
其中最主要的就是performLaunchActivity()方法了,在这里创建了最终的Activity实例,来看一下:
1 | private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { |
到此为止,startActivity()的所有流程就走了一遍