我正在参与掘金创作者训练营第4期,点击了解活动详情,一起学习吧!
Launcher应用进程启动流程 总结篇
在此前的Launcher应用启动流程Launcher应用启动流程(上)、Launcher应用启动流程(中)、Launcher应用启动流程(下)三篇文章的分析中,将Launcher应用进程的代码流程分析了一遍,本篇将对上述的整体流程进行总结汇总
Launcher应用流程启动
在安卓系统启动过程中,创建的第一个进程是zygote,在zygote中会分裂一个system_server进程,而在system_server进程后会启动各种服务等,而在这个过程中会初始化ActivityManagerService(简称AMS)服务,同时在最后通过调用AMS的systemReady函数来完成AMS的启动,在systemReady函数中,通过调用ActivityTaskManagerService(简称ATMS)的startHomeOnAllDisplays函数
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
mAtmInternal参数是一个ActivityTaskManagerInternal对象,关于其的类图结构如下
classDiagram
ActivityTaskManagerInternal <|-- LocalService
ActivityTaskManagerService *-- LocalService
class ActivityTaskManagerInternal {
+startHomeOnAllDisplays(int userId, String reason)* boolean
}
class ActivityTaskManagerService {
~LocalService
}
class LocalService {
<<final>>
+startHomeOnAllDisplays(int userId, String reason) boolean
}
从这个类图结构来看,ActivityTaskManagerInternal类是一个抽象类,而且startHomeOnAllDisplays函数是一个抽象方法,继承该类的LocalService实现了该抽象函数,且LocalService是ATMS的内部类
而且从ATMS服务的初始化中可以知道,其对象的mAtmInternal参数为ATMS.LocalService的实例
RootWindowContainer对象函数调用
RootWindowContainer对象是窗口绘制中的一个重要的类,它继承自WindowContainer对象,如下为其类图结构
classDiagram
WindowToken <|-- ActivityRecord
AppFreezeListener <|.. ActivityRecord
WindowManagerService *-- AppFreezeListener
WindowContainer <|-- WindowToken
ConfigurationContainer <|-- WindowContainer
Animatable <|.. WindowContainer
Freezable <|.. WindowContainer
TransactionReadyListener <|.. WindowContainer
Comparable <|.. WindowContainer
<<interface>> Animatable
<<interface>> Freezable
<<interface>> TransactionReadyListener
<<interface>> Comparable
SurfaceFreezer *-- Freezable
BLASTSyncEngine *-- TransactionReadyListener
<<abstract>> ConfigurationContainer
Task <|-- ActivityStack
WindowContainer <|-- Task
WindowContainer <|-- DisplayContent
DisplayContentInfo <|-- DisplayContent
<<interface>> DisplayContentInfo
WindowManagerPolicy <|-- DisplayContentInfo
<<interface>> WindowManagerPolicy
WindowContainer <|-- RootWindowContainer
class AppFreezeListener {
<<interface>>
#onAppFreezeTimeout() void
}
class ActivityRecord {
-Task task
#asActivityRecord() ActivityRecord
#getTask() Task
}
class WindowContainer {
#asActivityRecord() ActivityRecord
}
class ConfigurationContainer {
#getChildCount()* int
#getChildAt(int index) * E
#getParent()* ConfigurationContainer
}
class Animatable {
#start() void
#stop() void
#isRunning() boolean
}
ATMS.LocalService的startHomeOnAllDisplays函数会调用RootWindowContainer对象的startHomeOnAllDisplays函数,在这个函数中会获取当前设备系统中支持的所有显示设备,并对每一个设备获取其DisplayId并调用RootWindowContainer对象的startHomeOnDisplay函数
而在startHomeOnDisplay函数中会获取对应的显示设备Display的显示区域,并调用其startHomeOnTaskDisplayArea函数,而 在该函数中,
- 会通过ATMS的getHomeIntent函数获取需要查找的Intent意图,并且根据这个意图查找系统支持的ActivityInfo
- 同时调用ActivityStartController对象的startHomeActivity函数,正式开始启动对应Activity的流程
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {
// ......
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (taskDisplayArea == getDefaultTaskDisplayArea()) {
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
}
// ......
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
taskDisplayArea);
return true;
}
ActivityStarter
ActivityStartController对象是一个Activity启动控制器,其主要是将外部请求启动的Activity整理完成后交给ActivityStarter进行处理和启动,同时它还会为这些Activity加上一些必要的逻辑信息等,而在ActivityStartController对象的startHomeActivity函数中,主要做了
- 为将要启动的Activity设置对应的条件ActivityOptions
- 然后将上述生成的ActivityInfo交给ActivityStarter进行处理
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, TaskDisplayArea taskDisplayArea) {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (!ActivityRecord.isResolverActivity(aInfo.name)) {
// The resolver activity shouldn't be put in home stack because when the foreground is
// standard type activity, the resolver activity should be put on the top of current
// foreground instead of bring home stack to front.
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
final int displayId = taskDisplayArea.getDisplayId();
options.setLaunchDisplayId(displayId);
options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken
.toWindowContainerToken());
// ......
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
// ......
}
ActivityStarter对象在初始化后,为其设置对应参数后,调用execute函数来运行和启动这个ActivityInfo,ActivityStarter类中包含有一个内部类Request,这个类在ActivityStarter启动时主要包含了所有请求启动的数据。
接下来会调用其executeRequest函数来运行这个请求,在这个函数中
- 首先通过上述添加的ActivityOptions和ActivityInfo等参数为本次启动设置必要的参数
- 其次初始化一个包含所有Activity信息的ActivityRecord对象,并且调用startActivityUnchecked函数
- 在调用startActivityUnchecked函数后,通过ActivityStack的startActivityLocked函数将要启动的ActivityRecord添加到Activity堆栈中,从而在最后调用RootWindowContainer的resumeFocusedStacksTopActivities函数来启动这个Activity
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
// ......
mTargetStack.startActivityLocked(mStartActivity,
topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
mKeepCurTransition, mOptions);
if (mDoResume) {
// ......
if (!mTargetStack.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
// ......
} else {
// ......
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
}
// ......
return START_SUCCESS;
}
RootWindowContainer中恢复Activity启动
RootWindowContainer的resumeFocusedStacksTopActivities函数中,主要调用ActivityStack对象的resumeTopActivityUncheckedLocked函数,从而进一步调用resumeTopActivityInnerLocked函数,最终进入ActivityStackSupervisor的startSpecificActivity函数
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// ......
if (next.attachedToProcess()) {
// ......
} else {
// ......
mStackSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
通过ActivityStackSupervisor的startSpecificActivity函数,从而进入Launcher进程启动阶段
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// ......
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
Launcher应用进程启动
ATMS的startProcessAsync函数
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop, String hostingType) {
try {
// ......
// Post message to start process to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
主要通过初始化一个Message对象,并且通过AMS.H对象的sendMessage来处理这个Message消息 PooledLambda的obtainMessage函数中,会初始化一个PooledRunnable对象,并将其设置为生成的Message对象的Callback
其类图结构如下
classDiagram
PooledLambda <|-- PooledRunnable
Runnable <|-- PooledRunnable
ThrowingRunnable <|-- PooledRunnable
TraceNameSupplier <|-- PooledRunnable
<<interface>>PooledRunnable
<<interface>>PooledLambda
<<interface>>Runnable
<<interface>>ThrowingRunnable
<<interface>>TraceNameSupplier
PooledRunnable继承自Runnable是一个线程
而AMS.H的sendMessage函数,会将上述生成的Message对象添加到MessageQueue中,并且通过dispatchMessage函数分发这些Message给到AMS.H来处理
而根据Handler源码可知,当其所分发的Message包含Callback不为null的时候,会直接调用该Handler对象的handleCallback,从而直接运行这个Callback(此处为PooledRunnable对象)
从而直接调用ATMS的mAmInternal参数的startProcess函数,而mAmInternal为ActivityManagerInternal对象实例,
而ActivityManagerInternal类结构图如下
classDiagram
ActivityManagerInternal <|-- LocalService
<<abstract>> ActivityManagerInternal
<<final>> LocalService
ActivityManagerService *-- LocalService
class ActivityManagerInternal {
+startProcess(String, ApplicationInfo, boolean, boolean, String, ComponentName)* void
}
class LocalService {
+startProcess(String, ApplicationInfo, boolean, boolean, String, ComponentName) void
}
因此,最终会调用AMS.LocalService的startProcess函数,最终在ProcessList对象的startProcess函数中,调用Process.start函数通过zygote生成一个进程并启动
@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
// ......
synchronized (ActivityManagerService.this) {
// ......
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */, true /* keepIfLarge */);
}
}
// ......
}
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
keepIfLarge, null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}
// ....... 重载函数省略
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
// ......
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
// ......
} else {
try {
final Process.ProcessStartResult startResult = startProcess(hostingRecord,
entryPoint, app,
uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
requiredAbi, instructionSet, invokeWith, startTime);
handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
startSeq, false);
}
// ......
}
}
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
int mountExternal, String seInfo, String requiredAbi, String instructionSet,
String invokeWith, long startTime) {
// ......
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
new String[]{PROC_START_SEQ_IDENT + app.startSeq});
// ......
}
如此,Launcher应用进程被创建以及启动
Launcher应用进程启动流程时序图
感想
因为个人一边工作一边分析这个流程,同时Launcher应用进程启动流程非常复杂(针对于我的个人感受),分析过程中代码分支非常多,且参数详细结果不清晰,导致不仅花费时间长,且进展缓慢,由此如下的几点真实感受分享一下
- 对于源码分析,分支和结构复杂的模块,需要自己添加一些日志或者调试数据协助分析,而不能想当然的认为某一个分支应该走到或者不应该走到,这样容易误入歧途
- 源码分析的手段需要加强,很多很有用的调试工具,如AS的DEBUG功能,源码查看工具,流程图等一些协助源码分析的工具需要加强应用
- 源码分析过程中,有时需要追根溯源,有时需要浏览带过,度要自己把握