写在前面:这是“简单易懂说原理(热修复、插件化基础)”系列的第二篇文章,也是理解插件化原理的必备基础。阅读本文前须有Android系统启动流程及应用程序进程启动过程相关基础。
在前一篇文章中我们说到应用程序进程在创建的同时也创建了Binder线程池和消息循环。其实,在创建了Binder线程池后,应用程序进程还会创建并运行一个代表主线程的 ActivityThread,他管理着当前应用程序进程的主线程。
在本文中,我们将会经常提到ActivityThread。
一、根Activity的启动过程
根Activity是应用程序启动的第一个Activity,因此根Activity的启动过程在一般情况下我们也可以理解为是应用程序启动的过程。
根Activity的启动过程如下图所示。
其中,ApplicationThread是ActivityThread的内部类,是一个Binder。
- Launcher请求AMS。当我们点击图标时,就会通过Launcher请求AMS来启动该应用程序。其中这里会传递Intent.FLAG_ACTIVITY_NEW_TASK,使根Activity在新的任务栈中启动。
- AMS请求ApplicationThread。这部分有些复杂,涉及到两个流程(创建应用程序进程流程和启动根Activity流程),其中创建应用程序进程流程在这里就不赘述了,我们只来讲启动根Activity流程,也就是AMS到ApplicationThread的调用流程。如下图所示:
可以看到,AMS到ApplicationThread这一段的入口方法是startActivity()。
- ActivityRecord:用于描述一个Activity,用来记录一个Activity的所有信息。在这里我们在获取完Launcher进程的pid和uid后,创建了一个ActivityRecord,用于描述将要启动的Activity。
- TaskRecord:用来描述一个Activity任务栈,在这里其实我们也就是创建了一个新的Activity任务栈。需要注意的是,Activity任务栈是一个假象的模型,并不真实存在。
在创建新的TaskRecord后,去获取要启动的Activity所在的栈的栈顶不是处于停止状态的ActivityRecord,对于要启动的Activity由于是个根Activity,所以ActivityRecord为空。
接下来就是启动栈顶Activity。首先是获取这个即将启动的Activity所在的应用程序进程,之后就是在目标应用程序进程中启动Activity。
上面的这些逻辑都运行在AMS所在的进程中,但是我们在获取即将启动的Activity所在的应用程序进程后,会得到这个应用程序进程的ApplicationThread。我们知道ApplicationThread是一个Binder,因此,逻辑自然由AMS所在进程经过Binder通信来到了ActivityThread,也就是进入到了应用程序进程中。
- ActivityThread启动根Activity。在得到应用程序进程的ApplicationThread后,ApplicationThread会将启动Activity的参数封装成ActivityClientRecord,并向H类发送类型为LAUNCH_ACTIVITY的消息,且在发消息时将ActivityClientRecord传递过去。
这里H