在我的上一篇文章:
AJie:按下电源键后竟然发生了这一幕 —— Android 系统启动流程分析zhuanlan.zhihu.com我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS(ActivityManagerService) 会启动 Launcher 来展示我们手机中所有已安装的应用图标,点击图标后相应的应用程序将会被系统启动运行并展示在我们面前,那么,点击了图标之后系统道理做了哪些工作呢?应用进程是怎么被启动的呢?Activity 的生命周期是什么时候被谁调用的呢?本文将继续基于 Android Nougat 的 frameworks 层源码的解答这些问题。
阅读建议: 如果你是首次阅读这个过程的源码,建议你忽略一些细枝末节的代码,先抓主干代码,从整体上理解代码的执行流程(右下角文章目录视图中可以点击跳转到相应章节),否则将会被细节的代码扰乱思路。最后可以回头多看几遍,这时候如果有需要可以追踪一些枝干代码,做到融会贯通。
1. Launcher —— AMS
1.1 调用过程分析
1.1.1 Launcher.onClick
在 Launcher app 的主 Activity —— Launcher.java 中,App 图标的点击事件最终会回调 Launcher.java 中的 onClick 方法,
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java:
public
1.1.2 Launcher.onClickAppShortcut
如果是快捷方式图标,则调用 onClickAppShortcut 方法进而调用 startAppShortcutOrInfoActivity 方法:
@Thunk
1.1.3 Launcher.startActivity
获取相应 App 的 Intent 信息之后,调用 startActivity 方法:
private
1.1.4 Activity.startActivity
这里最终调用了 Activity 中的 startActivity 方法,并且设置 Flag 为 FLAG_ACTIVITY_NEW_TASK。到此为止,已经跟启动普通的 Activity 流程汇合起来了,继续往下分析。
frameworks/base/core/java/android/app/Activity.java:
@Override
1.1.5 Activity.startActivityForResult
调用 Activity 的 startActivityForResult 方法
public
1.1.6 Instrumentation.execStartActivity
frameworks/base/core/java/android/app/Instrumentation.java:
public
1.1.7 ActivityManagerProxy.startActivity
以上过程是在 Launcher App 所在的进程中发生的,在我的另外一篇文章
AJie:借助 AIDL 理解 Android Binder 机制——AIDL 的使用和原理分析zhuanlan.zhihu.com中我们分析了 AIDL 的实现过程,由于远程 Service 跟使用 Service 的 Activity 不在同一个进程中,因此他们之间交互需要通过 Binder IPC 机制的支持,在这个过程中Client 首先获取到 Server 端的代理对象,在 Client 看来 Server 代理对象同样具有 Server 本地对象承诺的能力,因此 Client 可以调用 Server 代理对象跟 Sever 本地对象进行数据交互,Binder 驱动作为桥梁在他们中间起到中间人的作用。
在Android 系统启动流程分析中曾经分析过,AMS 是运行在 system_server 线程中的,这时 AMS 就相当于 AIDL 中的远程 Service,App 进程要与 AMS 交互,需要通过 AMS 的代理对象 AMP(ActivityManagerProxy) 来完成,来看 ActivityManagerNative.getDefault() 拿到的是什么:
frameworks/base/core/java/android/app/ActivityManagerNative.java:
static
getDefault 是一个静态变量:
private
同样,在文章
AJie:借助 AIDL 理解 Android Binder 机制——Binder 来龙去脉zhuanlan.zhihu.com中也讲到过:
ServiceManager 是 Binder IPC 通信过程的核心,是上下文的管理者,Binder 服务端必须先向 ServerManager 注册才能够为客户端提供服务,Binder 客户端在与服务端通信之前需要从 ServerManager 中查找并获取 Binder 服务端的引用。
这里通过 "activity" 这个名字向 ServiceManager 查询 AMS 的引用,获取 AMS 的引用后,调用 asInterface 方法:
static
因为 AMS 与 Launcher App 不在同一个进程中,这里返回的 IBinder 对象是一个 Binder 代理对象,因此这类将其包装成 AMP(ActivityManagerProxy) 对象并返回,AMP 是 AMN(ActivityManagerNative) 的内部类,查看 AMP 类 :
class
可以看到,AMP 里面将客户端的请求通过 mRemote.transact 进行转发,mRemote 对象正是 Binder 驱动返回来的 Binder Proxy 对象,通过 Binder Proxy,Binder 驱动最终将调用处于 Binder Server 端 AMN 中的 onTransact 方法:
@Override
1.1.8 ActivityManagerService.startActivity
AMN 是一个抽象类,它的 startActivity 为抽象方法,具体的实现在 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 中:
@Override
1.2 小结
从 Launcher App 到 AMS 的调用过程中使用了 Binder IPC 机制,如果你已经看了上面提到的我之前写的两篇文章——借助 AIDL 理解 Android Binder 机制——Binder 来龙去脉和借助 AIDL 理解 Android Binder 机制——AIDL 的使用和原理分析,并且运行了文章中使用到的 Demo,你应该可以发现,相对于 AIDL 的调用过程,调用方 Launcher App 相当于 AIDL 过程中的 Activity 所在的 App,充当 Clinent 的角色;AMS 相当于远程 Service 的角色,充当 Server 端角色,他们的调用过程总体上都是一样的。
从 Launcher App 到 AMS 的时序图如下:
2. AMS —— zygote
2.1 调用过程分析
2.1.1 ActivityManagerService.startActivityAsUser
接着从 AMS 的 startActivityAsUser 方法开始分析:
@Override
2.1.2 ActivityStarter.startActivityMayWait
继续跟进 frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java:
final
2.1.3 ActivityStarter.startActivityLocked
查看 startActivityLocked 方法:
final
2.1.4 ActivityStarter.doPendingActivityLaunchesLocked
查看 doPendingActivityLaunchesLocked 方法:
final
2.1.5 ActivityStarter.startActivityUnchecked
查看 startActivityUnchecked 方法:
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
...
// 调用 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked 方法
mSupervisor.resumeFocusedStackTopActivityLocked();
...
return START_SUCCESS;
}
2.1.6 ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java:
boolean
2.1.7 ActivityStack.resumeTopActivityUncheckedLocked
查看 ActivityStack 的 resumeTopActivityUncheckedLocked 方法:
boolean
2.1.8 ActivityStack.resumeTopActivityInnerLocked
查看 resumeTopActivityInnerLocked 方法:
private
2.1.9 ActivityStackSupervisor.startSpecificActivityLocked
回到 ActivityStackSupervisor 的 startSpecificActivityLocked 方法:
void
首先,在方法中获取了当前 Activity 附属的 Application,如果已经在运行了,说明这个 App 是已经被启动过了的,这时候调用 realStartActivityLocked 方法就可以进入下一步的流程了,同一个 App 中不同 Activity 的相互启动就是走的这个流程。当 Application 没有运行的时候,就需要调用 AMS 的 startProcessLocked 方法启动一个进程去承载它然后完成后续的工作,顺便铺垫一下,当新进程被启动完成后还会调用回到这个方法,查看 AMS 的 startProcessLocked 方法:
2.1.10 ActivityManagerService.startProcessLocked
final
2.1.11 ActivityManagerService.startProcessLocked
调用 startProcessLocked 方法:
final
2.1.12 ActivityManagerService.startProcessLocked
调用 startProcessLocked 的重载方法:
private
2.1.13 Process.start
frameworks/base/services/core/java/android/os/Process.java:
public
2.1.14 Process.startViaZygote
查看 startViaZygote 方法:
private
2.1.15 Process.zygoteSendArgsAndGetResult、Process.openZygoteSocketIfNeeded
查看 zygoteSendArgsAndGetResult 方法:
private
在 zygoteSendArgsAndGetResult 中等待 Socket 服务端,也就是 zygote 进程返回创建新进程的结果,这里 zygoteState 参数是由 openZygoteSocketIfNeeded 方法返回的,openZygoteSocketIfNeeded 方法则负责根据 abi 向 Zygote 进程发起连接请求:
private
2.2 小结
如果是从桌面新启动一个 App 中的 Activity,此时是没有进程去承载这个 App 的,因此需要通过 AMS 向 zygote 继承发起请求去完成这个任务,AMS 运行在 system_server 进程中,它通过 Socket 向 zygote 发起 fock 进程的请求,从 AMS 开始的调用时序图如下:
3. zygote —— ActivityThread
3.1 调用过程分析
3.1.1 ZygoteInit.main
在 Android 系统启动流程分析 文中提到过 zygote 进程的其中一项任务就是:
调用 registerZygoteSocket() 函数建立 Socket 通道,使 zygote 进程成为 Socket 服务端,并通过 runSelectLoop() 函数等待 ActivityManagerService 发送请求创建新的应用程序进程。
zygote 终于要再次上场了!接下来从 ZygoteInit.java 的 main 方法开始回顾一下 zygote 进程的工作:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:
public
3.1.2 ZygoteInit.runSelectLoop
查看 runSelectLoop 方法:
private
3.1.3 ZygoteConnection.runOnce
查看 frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java 的 runOnce 方法:
boolean
3.1.4 ZygoteConnection.handleChildProc
首先解析 Socket 客户端传过来的参数,Zygote.java 的 forkAndSpecialize 返回的 pid == 0 的时候表示此时在 fock 出来的子进程中执行,继续调用 handleChildProc 方法,并将参数继续层层传递:
private
3.1.5 RuntimeInit.zygoteInit
查看 frameworks/base/core/java/com/android/internal/os/RuntimeInit.java 的 zygoteInit 方法:
public
3.1.6 RuntimeInit.applicationInit
继续调用 applicationInit 方法:
private
3.1.7 RuntimeInit.invokeStaticMain
主要调用了 invokeStaticMain 方法:
private
3.1.8 MethodAndArgsCaller.run
回到 ZygoteInit 的 main 方法:
public
跟 system_server 进程的启动过程一样,这里同样通过抛出异常的方式来清空调用 ActivityThread.main 之前的方法栈帧。
ZygoteInit 的 MethodAndArgsCaller 类是一个 Exception 类,同时也实现了 Runnable 接口:
public
3.1.9 ActivityThread .main
最后通过反射调用到 ActivityThread 的 main 方法:
public
3.2 小结
zygote 进程作为 Socket 服务端在接收到作为客户端的 AMS 发送过来的请求和参数之后,fock 出新的进程并根据各种参数进程了初始化的工作,这个过程和 zygote 启动 system_server 进程的过程如出一辙,时序图如下所示:
4. ActivityThread —— Activity
4.1 调用过程分析
4.1.1 ActivityThread.attach
上一小节的最后,ActivityThread 的 main 通过反射被运行起来了,接着会调用 ActivityThread 的 attach 方法:
private
这里,我们再一次通过 Binder IPC 机制跟 AMS 通信,通信模型跟前面 Launcher App 调用 AMS 的 startActivity 方法一样,getDefault 过程不重复分析,这次是调用了 AMS 的 attachApplication 方法,注意这里将 ApplicationThead 类型的 mAppThread 对象作为参数传递了过去,ApplicationThead 是 ActivityThread 的一个内部类,后面我们会讲到,先查看 AMP 的 attachApplication 方法:
4.1.2 ActivityManagerProxy.attachApplication
public
4.1.3 ActivityManagerNative.onTransact
public
asInterface 将 ActivityThread 对象转换成了 ApplicationThreadNative(ATN) 的 Binder 代理对象 ApplicationThreadProxy(ATP),并作为参数传给 attachApplication 方法,其中 ATP 是 ATN 的内部类。
4.1.4 ActivityManagerService.attachApplication
public
4.1.5 ActivityManagerService.attachApplicationLocked
private
首先,通过 ATP 使用 Binder 向 ATN 发起 bindApplication 请求,然后通过 normalMode 字段判断是否为 Activity,如果是则执行 ActivityStackSupervisor 的 attachApplicationLocked 方法。
4.1.5.1 ActivityThread.java::ApplicationThread.bindApplication
thread 对象类型是 ATP,通过 Binder 驱动调到了 ATN 的方法,ATN 是一个抽象类,它的实现都委托给了 ApplicationThread(这跟 AMS 跟 AMN 的关系一样),ApplicationThread 作为 ActivityThread 的内部类存在,它的 binderApplication 方法如下:
ActivityThread.java::ApplicationThread:
public
H 是 ActivityThread 中的一个 Handler 对象,用于处理发送过来的各种消息:
private
调用了 handleBindApplication 方法:
private
4.1.5.2 ActivityStackSupervisor.attachApplicationLocked
在 4.1.4 小节中通过 Binder 向 ActivityThread 发起 bindApplication 请求后,会根据启动组件的类型去做相应的处理,如果是 Acitivity,则会调用 ActivityStackSupervisor 的 attachApplicationLocked 方法:
boolean
4.1.5.2.1 ActivityStackSupervisor.realStartActivityLocked
前面 2.1.8 ActivityStackSupervisor.startSpecificActivityLocked 小节中分析过,如果当前 Activity 依附的 Application 已经被启动,则调用 realStartActivityLocked 方法,否则创建新的进程,再创建新的进程之后,两个流程的在这里合并起来了:
final
这里有一次使用 Binder 调用 ApplicationThread 的 scheduleLaunchActivity 方法。
4.1.5.2.2 ApplicationThread.scheduleLaunchActivity
public
上面提到过,H 是 ActivityThread 中一个 Handler 类,它接收到 LAUNCH_ACTIVITY 消息后会调用 handleLaunchActivity 方法。
4.1.5.2.3 ActivityThread.handleLaunchActivity
private
4.1.4.2.4 ApplicationThread.performLaunchActivity
private
4.1.5.2.5 Instrumentation.callActivityOnCreate
public
4.1.5.2.6 Activity.performCreate
final
终于,onCreate 方法被调用了!!!
4.2 小结
从 ActivityThread 到最终 Activity 被创建及生命周期被调用,核心过程涉及到了三次 Binder IPC 过程,分别是:ActivityThread 调用 AMS 的 attachApplication 方法、AMS 调用 ApplicationThread 的 bindApplication 方法、ASS 调用 Application 的 attachApplicationLocked 方法,整个过程的时序图如下:
5. 总结
纵观整个过程,从 Launcher 到 AMS、从 AMS 再到 Zygote、再从 Zygote 到 ActivityThread,最后在 ActivitThread 中层层调用到 Activity 的生命周期方法,中间涉及到了无数的细节,但总体上脉络还是非常清晰的,各个 Android 版本的 Framework 层代码可以某些过程的实现不太一样,但是整个调用流程大体上也是相同的,借用 Gityuan 大神的一张图作为结尾:
系列文章
AJie:按下电源键后竟然发生了这一幕 —— Android 系统启动流程分析zhuanlan.zhihu.com参考文章
startActivity启动过程分析 - Gityuan博客 | 袁辉辉的技术博客
Android深入四大组件(一)应用程序启动过程(前篇)
如果你对文章内容有疑问或者有不同的意见,欢迎留言,我们一同探讨。