Activity启动流程 (Android13)
本文以时序图的形式来展示activity的启动过程,相比于贴源码会更加直观。本文的讲解的流程是基于MainActivity使用standard模式启动SecondActivity,且两个Activity都在同一个应用中,最后的部分也会讲解一下进程的启动。
第一阶段:执行startActivity
zenuml
group App {
<<App>> act as Activity
<<App>> ins as Instrumentation
}
group AMS {
<<AMS>> atms as ActivityTaskManagerService #F0F8FF
ActivityStarter #F0F8FF
}
act.startActivity {
act.startActivityForResult {
ins.execStartActivity {
atms.startActivity {
atms.startActivityAsUser {
//没有缓存则创建
new ActivityStarter()
ActivityStarter."① execute"
}
}
}
}
}
zenuml
<<AMS>> ActivityStarter #F0F8FF
ActivityStarter."① execute" {
executeRequest {
new ActivityRecord()
startActivityUnchecked {
startActivityInner {
Task.addChild
Task.startActivityLocked
RootWindowContainer.resumeFocusedTasksTopActivities {
Task.resumeTopActivityUncheckedLocked {
resumeTopActivityInnerLocked {
TaskFragment.resumeTopActivity {
//pause当前activity
"② startPausing()"
if (! isProcessRunning) {
ActivityTaskManagerService.startProcessAsync
}
}
}
}
}
}
handleStartResult
postStartActivityProcessing
}
}
}
第二阶段:pause当前activity
启动SecondActivity之前会先执行MainActivity的pause操作:
在Android 9之前的版本,ActivityThread中通过LAUNCH_ACTIVITY消息来启动activity,源码如下:
1 | //android\app\ActivityThread.java |
但从Andorid 9开始,ActivityThread去掉了LAUNCH_ACTIVITY PAUSE_ACTIVITY RESUME_ACTIVITY等消息,而是改成了EXECUTE_TRANSACTION,通过ClientTransaction这套机制来执行activity生命周期流程,相关源码如下:
1 | public void handleMessage(Message msg) { |
下面是ClientTransaction类图:
第三阶段:启动新Activity
下面继续Activity启动流程:
执行SecondAcitivity的启动流程:
第四阶段:View添加到Window
下面这个时序图是对上面时序图的进一步细化,① ② ③ ④与上面的序号一对一对应。
zenuml
group {
<<App>> ActivityThread
<<App>> SecondActivity
PhoneWindow
DecorView
<<App>> WindowManagerGlobal
ViewRootImpl
}
SecondActivity."① attach" {
attachBaseContext
new PhoneWindow()
PhoneWindow.setWindowManager
}
SecondActivity."② onCreate()" {
setContentView {
PhoneWindow.installDecor {
new DecorView()
mContentParent = generateLayout()
"mContentParent.addView"
}
}
}
SecondActivity."③ onStart()"
ActivityThread.handleResumeActivity {
SecondActivity."④ onResume()"
DecorView.setVisibility(INVISIBLE)
WindowManagerGlobal.addView(DecorView) {
new ViewRootImpl()
"mViews.add(DecorView)"
"mRoots.add(ViewRootImpl)"
ViewRootImpl.setView(DecorView)
}
SecondActivity.makeVisible {
DecorView.setVisibility(VISIBLE) {
ViewRootImpl.invalidateChild {
invalidate {
scheduleTraversals
}
}
}
}
}
Activity.onCreate()中通过调用setContentView来触发DecorView的创建,DecorView就是rootView(View#getRootView)。通过Hierarchy Viewer看下DecorView结构:

用户自定义的View会被添加到PhoneWindow.mContentParent中,而mContentParent是DecorView的一个子孙View。Activity.onResume()之后就会就会把DecorView添加到WindowManagerGlobal中,对生成对应的ViewRootImpl。ViewRootImpl就是DecorView的parent。
最后阶段就会执行UI的渲染,对应ViewRootImpl.scheduleTraversals。
下面是Activity、Task之间的类图关系:
启动新APP进程
如果需要启动的activity不在同一个app中,就需要启动新的进程。
zenuml
ActivityTaskManagerService.startProcessAsync {
H.sendMessage {
ActivityManagerService.startProcess {
startProcessLocked {
ProcessList.startProcessLocked {
newProcessRecordLocked {
new ProcessRecord()
}
//with ProcessRecord
startProcessLocked {
ProcessList."配置runtimeFlags"
//异步启动线程
ProcessList -> ActivityManagerService : mProcStartHandler.post
}
}
}
}
}
}
zenuml
ActivityManagerService."mProcStartHandler.dispatchMessage" {
ProcessList.handleProcessStart {
startProcess {
ProcessStartResult = Process.start {
ProcessStartResult = ZygoteProcess.start {
startViaZygote {
ZygoteProcess."组装参数列表args"
zygoteSendArgsAndGetResult {
//通过LocalSocket向zygote发送进程启动参数
//并阻塞读取进程pid
attemptZygoteSendArgsAndGetResult
}
}
}
}
}
handleProcessStartedLocked {
ActivityManagerService.addPidLocked {
ActivityTaskManagerService."onProcessMapped(pid, WindowProcessController)" {
ActivityTaskManagerService."mProcessMap.put(pid, proc)"
}
}
}
}
}
1 | //android-13.0.0_r41\frameworks\base\core\java\android\os\ZygoteProcess.java |
新的app进程启动运行的入口是ActivityThread.main函数:
1 | public static void main(String[] args) { |
zenuml
group App {
ApplicationThread
Application
ActivityThread
mH
}
group AMS {
ActivityManagerService
}
ActivityThread.attach {
ActivityManagerService.attachApplication {
Binder.getCallingPid
attachApplicationLocked {
"根据pid获取ProcessRecord"
ApplicationThread.bindApplication {
mH.sendMessage(BIND_APPLICATION)
}
}
}
}
ActivityThread.handleMessage(BIND_APPLICATION) {
handleBindApplication {
new Application()
Application.attachBaseContext()
Application.onCreate()
}
}