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之前会先执行MainActivitypause操作:

AMSAPPTaskFragmentTaskFragmentClientTransactionClientTransactionActivityRecordActivityRecordActivityThreadActivityThreadTransactionExecutorTransactionExecutorMainActivityMainActivity② startPausing()schedulePauseActivityPauseActivityItem.obtain()ClientLifecycleManager.scheduleTransactionobtainsetLifecycleStateRequest(PauseActivityItem)schedule()[ApplicationThread]→scheduleTransaction(this)scheduleTransactionsendMessage:EXECUTE_TRANSACTIONhandleMessage()execute(transaction)[PauseActivityItem]→execute()handlePauseActivityonPause()[PauseActivityItem]→postExecuteactivityPaused③ completePause

在Android 9之前的版本,ActivityThread中通过LAUNCH_ACTIVITY消息来启动activity,源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
//android\app\ActivityThread.java
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;

但从Andorid 9开始,ActivityThread去掉了LAUNCH_ACTIVITY PAUSE_ACTIVITY RESUME_ACTIVITY等消息,而是改成了EXECUTE_TRANSACTION,通过ClientTransaction这套机制来执行activity生命周期流程,相关源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
......
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;

下面是ClientTransaction类图:

Activity Transaction

第三阶段:启动新Activity

下面继续Activity启动流程:

AMSTaskFragmentTaskFragmentRootWindowContainerRootWindowContainerTaskTaskActivityTaskSupervisorActivityTaskSupervisor③ completePauseresumeFocusedTasksTopActivitiesresumeTopActivityUncheckedLockedresumeTopActivityInnerLockedresumeTopActivity④ startSpecificActivity

执行SecondAcitivity的启动流程:

AMSAPPActivityTaskSupervisorActivityTaskSupervisorActivityRecordActivityRecordClientTransactionClientTransactionApplicationThreadApplicationThreadActivityThreadActivityThread④ startSpecificActivityrealStartActivityLockedsetProcessobtainLaunchActivityItem.obtainaddCallback(LaunchActivityItem)ResumeActivityItem.obtainsetLifecycleStateRequest(ResumeActivityItem)[ClientLifecycleManager]→scheduleTransaction  schedulescheduleTransactionscheduleTransaction⑤ sendMessage:EXECUTE_TRANSACTIONActivityTaskManagerService.startProcessAsync APPActivityThreadActivityThreadTransactionExecutorTransactionExecutorContextImplInstrumentationInstrumentationSecondActivity⑤ handleMessageEXECUTE_TRANSACTIONexecute(transaction)LaunchActivityItem.executehandleLaunchActivityperformLaunchActivitycreateBaseContextForActivity[ContextImpl]→createActivityContextContextImplnewActivitySecondActivity① attachcallActivityOnCreate② onCreate()executeLifecycleStatecycleToPathperformLifecycleSequencehandleStartActivityperformStartcallActivityOnStart③ onStart()ResumeActivityItem.executehandleResumeActivityperformResumeActivityperformResumecallActivityOnResume④ onResume()

第四阶段: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结构:

DecorView示例

用户自定义的View会被添加到PhoneWindow.mContentParent中,而mContentParent是DecorView的一个子孙View。Activity.onResume()之后就会就会把DecorView添加到WindowManagerGlobal中,对生成对应的ViewRootImpl。ViewRootImpl就是DecorView的parent。

最后阶段就会执行UI的渲染,对应ViewRootImpl.scheduleTraversals

下面是Activity、Task之间的类图关系:

WindowContainerWindowContainerTaskFragmentTaskRootDisplayAreaDisplayContentWindowContainerDisplayAreaDisplayAreaWindowContainerDisplayContentRootWindowContainerWindowContainerWindowStateWindowTokenActivityRecord1n1nmChildrenn1

启动新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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//android-13.0.0_r41\frameworks\base\core\java\android\os\ZygoteProcess.java
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
try {
final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

//通过LocalSocket将进程启动参数传输给zygote进程
zygoteWriter.write(msgStr);
zygoteWriter.flush();

Process.ProcessStartResult result = new Process.ProcessStartResult();
//读取新进程的pid
result.pid = zygoteInputStream.readInt();
result.usingWrapper = zygoteInputStream.readBoolean();

if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}

return result;
} catch (IOException ex) {
zygoteState.close();
Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
+ ex.toString());
throw new ZygoteStartFailedEx(ex);
}
}

新的app进程启动运行的入口是ActivityThread.main函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
......
//初始化主线程Looper
Looper.prepareMainLooper();

......
//创建ActivityThread
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);

if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}

......
//启动主线程消息循环
Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");
}

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()
    }
}