「这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战」。
Launcher启动流程分析(下)
在此前的两篇文档Launcher启动流程分析(上) Launcher启动流程分析(中)中有分析过,从SystemServer中启动AMS后,通过AMS的systemReady函数启动Launcher应用的启动流程,在这个过程中,通过调用ActivityStarter的execute函数,最终会在ActivityStarter对象的startActivityInner函数中,通过ActivityStack的startActivityLocked函数来将对应的ActivityRecord添加到ActivityStack中,并且通过RootWindowContainer对象的resumeFocusedStacksTopActivities函数来启动这个Activity,本篇我们将来分析下这个流程,以及最终Launcher应用的主界面显示的具体过程
ActivityRecord对象添加到ActivityStack流程分析
ActivityRecord类是包含了Activity具体信息的一个类,且其一般被用作添加到ActivityStack堆栈中的实例,此处通过ActivityStack的startActivityLocked函数完成添加任务
// 注:此处传入的第一个参数ActivityRecord对象为在ActivityStarter.executeRequest函数中初始化的一个ActivityRecord对象
// 第二个参数为包含有Launcher应用的主Activity信息的一个ActivityRecord对象
// 第三个参数newTask为true
// 第四个参数keepCurTransition为false
// 第五个参数options为ActivityStartController对象调用startHomeActivity时初始化的一个ActivityOptions
// 和后续新建的SafeActivityOptions对象后设置的一个ActivityOptions对象的融合
void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity,
boolean newTask, boolean keepCurTransition, ActivityOptions options) {
// 从前述的代码中分析,此处获取到的Task不为null
Task rTask = r.getTask();
// 根据代码判断,此处options.getAvoidMoveToFront()并未有设置过,因此此处为false,即整体的allowMoveToFront参数为true
// 根据判断,此处isOrhasTask参数返回值为true
final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
final boolean isOrhasTask = rTask == this || hasChild(rTask);
// mLaunchTaskBehind tasks get placed at the back of the task stack.
if (!r.mLaunchTaskBehind && allowMoveToFront && (!isOrhasTask || newTask)) {
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
// 将当前的rTask参数设置为
positionChildAtTop(rTask);
}
Task task = null;
if (!newTask && isOrhasTask) {
// ...... 分支无法运行,此处newTask为true,因此跳过
}
// Place a new activity at top of stack, so it is next to interact with the user.
// If we are not placing the new activity frontmost, we do not want to deliver the
// onUserLeaving callback to the actual frontmost activity
final Task activityTask = r.getTask();
if (task == activityTask && mChildren.indexOf(task) != (getChildCount() - 1)) {
// ...... 分支无法运行,此处newTask为true,因此跳过
}
task = activityTask;
// ...... 日志打印代码省略
// 接下来将上述初始化的ActivityRecord对象放置到当前的Task中的mWindowList中的最上层
task.positionChildAtTop(r);
// The transition animation and starting window are not needed if {@code allowMoveToFront}
// is false, because the activity won't be visible.
// 此处由于前述代码将ActivityRecord添加到Task中,此处的hasActivity()函数将返回true
// 而前述分析allowMoveToFront = true
// 因此此处if分支会进入
if ((!isHomeOrRecentsStack() || hasActivity()) && allowMoveToFront) {
// ...... 此处对于Activity的启动模式等进行设置,不再赘述
}
// ...... 无效分支代码省略
}
从这段代码可知,此处最主要的任务是将ActivityRecord对象存放于Task对象参数mWindowList的最上层TOP,当然从前述代码分析可知,此处实质上是一个继承自Task类的ActivityStack对象
此后通过其他方式将当前的Activity启动
Activity的具体启动流程
由前文分析可知,在Activity的启动过程中,主要是通过RootWindowContainer的resumeFocusedStacksTopActivities函数将对应添加到Task对象(ActivityStack对象)中的ActivityRecord对象运行起来
RootWindowContainer.java
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
// ...... 条件判断不满足,代码省略
boolean result = false;
// 分析前述的代码可知,此处的targetStack.isTopStackInDisplayArea函数返回为true
if (targetStack != null && (targetStack.isTopStackInDisplayArea()
|| getTopDisplayFocusedStack() == targetStack)) {
// 调用对应的ActivityStack对象targetStack的resumeTopActivityUncheckedLocked函数
// 注意此处传入的两个参数,均是从ActivityStarter中传入的,target包含了需要启动的Activity的基本信息的ActivityRecord对象
// targetOptions为此前说明过的ActivityStartController对象调用startHomeActivity时初始化的一个ActivityOptions
// 和后续新建的SafeActivityOptions对象后设置的一个ActivityOptions对象的融合
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
// ...... 与功能暂不相关,暂不分析,代码省略
return result;
}
ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
// ...... 条件判断不满足代码省略
boolean result = false;
try {
// Protect against recursion.
mInResumeTopActivity = true;
// 继续调用resumeTopActivityInnerLocked函数
result = resumeTopActivityInnerLocked(prev, options);
// ......
} finally {
mInResumeTopActivity = false;
}
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// ...... 条件判断不满足代码省略
// Find the next top-most activity to resume in this stack that is not finishing and is
// focusable. If it is not focusable, we will fall into the case below to resume the
// top activity in the next focusable task.
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
final boolean hasRunningActivity = next != null;
// ...... 条件判断不满足代码省略
mRootWindowContainer.cancelInitializingActivities();
// Remember how we'll process this pause/resume situation, and ensure
// that the state is reset however we wind up proceeding.
boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
// ...... 条件判断不满足代码省略
next.delayedResume = false;
final TaskDisplayArea taskDisplayArea = getDisplayArea();
// ...... 条件判断不满足代码省略
// The activity may be waiting for stop, but that is no longer
// appropriate for it.
mStackSupervisor.mStoppingActivities.remove(next);
next.setSleeping(false);
// ...... 条件判断不满足代码省略
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
ActivityRecord lastResumed = null;
final ActivityStack lastFocusedStack = taskDisplayArea.getLastFocusedStack();
// ...... 条件判断不满足代码省略
// We are starting up the next activity, so tell the window manager
// that the previous one will be hidden soon. This way it can know
// to ignore it when computing the desired screen orientation.
boolean anim = true;
final DisplayContent dc = taskDisplayArea.mDisplayContent;
// ...... 条件判断不满足代码省略
if (anim) {
next.applyOptionsLocked();
} else {
next.clearOptionsLocked();
}
mStackSupervisor.mNoAnimActivities.clear();
if (next.attachedToProcess()) {
// ...... 条件判断不满足代码省略
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(null /* prev */, false /* newTask */,
false /* taskSwich */);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
// 此处最终会调用这边的startSpecificActivity函数
mStackSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
从如上的代码看,此处最终会调用ActivityStackSupervisor对象的startSpecificActivity函数
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// ...... 功能无关代码省略
final boolean isTop = andResume && r.isTopRunningActivity();
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
此处会调用ATMS的startProcessAsync函数
ATMS.java
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);
}
// ......
}
可以看到,这边主要是通过PooledLambda对象的obtainMessage函数来初始化一个Message,然后在ATMS.H对象中处理
static <A, B, C, D, E, F, G> Message obtainMessage(
HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
此处直接初始化了一个PooledRunnable对象,然后通过Message对象的setCallback函数设置该回调 了解Handler处理消息的流程可知,在Handler调用sendMessage发送消息的时候,会将Message添加到Handler对应的MessageQueue中,从而在对应的Looper对象中通过无限循环从MessageQueue中获取对应的Message,并且调用对应的Handler对象的dispatchMessage函数来分发消息,而在Handler的dispatchMessage函数中
Handler.java
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
也就是说,当Handler的dispatchMessage被调用时,若Message的callback回调函数参数被设置,则直接调用Handler的handleCallback函数
private static void handleCallback(Message message) {
message.callback.run();
}
也就是说,此处会运行这个callback 再回头看下PooledRunnable类的结构
classDiagram
PooledLambda <|-- PooledRunnable
Runnable <|-- PooledRunnable
ThrowingRunnable <|-- PooledRunnable
TraceNameSupplier <|-- PooledRunnable
<<interface>>PooledRunnable
<<interface>>PooledLambda
<<interface>>Runnable
<<interface>>ThrowingRunnable
<<interface>>TraceNameSupplier
也就是说,此处的PooledRunnable是一个Runnable对象,因此,调用其run函数,最终会运行到上述生成Message是传入的第一个参数ActivityManagerInternal::startProcess函数索引,
classDiagram
ActivityManagerService *-- LocalService
ActivityManagerInternal <|-- LocalService
而追踪ActivityManagerInternal对象mAmInternal的实例,会发现它为AMS.LocalService对象,因此
// 此处需要注意的是,这边函数中传入的六个参数,追踪其代码可以知道,在Message通过PooledLambda.obtainMessage函数初始化的时候
// 第一个参数为函数索引,第二个参数为实质调用第一个函数索引参数的对象实例,第3-8个参数即为此处传入的六个参数
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
// ......
synchronized (ActivityManagerService.this) {
// If the process is known as top app, set a hint so when the process is
// started, the top priority can be applied immediately to avoid cpu being
// preempted by other processes before attaching the process of top app.
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 */);
}
ProcessList.java
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
Runnable crashHandler) {
long startTime = SystemClock.uptimeMillis();
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkSlow(startTime, "startProcess: after getProcessRecord");
if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
// ...... 分支代码省略
} else {
// When the user is explicitly starting a process, then clear its
// crash count so that we won't make it bad until they see at
// least one crash dialog again, and make the process good again
// if it had been bad.
// ...... 日志打印代码省略
mService.mAppErrors.resetProcessCrashTimeLocked(info);
if (mService.mAppErrors.isBadProcess(info.processName, info.uid)) {
// ...... 日志打印代码省略
mService.mAppErrors.clearBadProcess(info.processName, info.uid);
if (app != null) {
app.bad = false;
}
}
}
}
// ...... 分支代码省略
if (app == null) {
checkSlow(startTime, "startProcess: creating new process record");
// 创建一个ProcessRecord,并将其添加到ProcessList中
app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
// ...... 分支代码省略
app.crashHandler = crashHandler;
app.isolatedEntryPoint = entryPoint;
app.isolatedEntryPointArgs = entryPointArgs;
if (precedence != null) {
app.mPrecedence = precedence;
precedence.mSuccessor = app;
}
checkSlow(startTime, "startProcess: done creating new process record");
}
// ...... 分支代码省略
// 调用startProcessLocked函数启动上述创建的ProcessRecord
final boolean success =
startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
checkSlow(startTime, "startProcess: done starting proc!");
return success ? app : null;
}
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
boolean mountExtStorageFull, String abiOverride) {
// ......
try {
// ......
final String seInfo = app.info.seInfo
+ (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
final String entryPoint = "android.app.ActivityThread";
// 最终会在调用同名函数startProcessLocked
return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);
}
// ...... catch remoteexception code delete
}
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) {
app.pendingStart = true;
app.killedByAm = false;
app.removed = false;
app.killed = false;
// ......
app.mDisabledCompatChanges = null;
if (mPlatformCompat != null) {
app.mDisabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info);
}
final long startSeq = app.startSeq = ++mProcStartSeqCounter;
app.setStartParams(uid, hostingRecord, seInfo, startTime);
app.setUsingWrapper(invokeWith != null
|| Zygote.getWrapProperty(app.processName) != null);
mPendingStarts.put(startSeq, app);
if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
// ......
// 直接运行对应的Runnable并运行
mService.mProcStartHandler.post(() -> handleProcessStart(
app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
requiredAbi, instructionSet, invokeWith, startSeq));
return true;
} else {
// ......
}
}
private void handleProcessStart(final ProcessRecord app, final String entryPoint,
final int[] gids, final int runtimeFlags, int zygotePolicyFlags,
final int mountExternal, final String requiredAbi, final String instructionSet,
final String invokeWith, final long startSeq) {
// ......
try {
// startProcess,这边会启动ActivityThread对象
final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,
entryPoint, app, app.startUid, gids, runtimeFlags, zygotePolicyFlags,
mountExternal, app.seInfo, requiredAbi, instructionSet, invokeWith,
app.startTime);
synchronized (mService) {
handleProcessStartedLocked(app, startResult, startSeq);
}
}
// ......
}
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) {
try {
// ......
// 根据此前的代码,此处的hostingRecord.mHostingZygote = REGULAR_ZYGOTE
final Process.ProcessStartResult startResult;
if (hostingRecord.usesWebviewZygote()) {
// ......
} else if (hostingRecord.usesAppZygote()) {
// ......
} else {
// 启动进程,这边的entruPoint = "android.app.ActivityThread"
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});
}
checkSlow(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
最后通过Process的start函数,在zygote中fork一个相应的进程,并且通过此处的ActivityThread对象的main函数以及传入的参数,调用相关的函数来初始化应用 其实从这块代码来看,ActivityThread对象是每一个进程都包含一个该对象,当然,这个对象肯定需要在AMS中进行注册
总结
如上,此篇我们分析了Launcher应用进程的启动流程,ActivityThread对象的初始化,以及zygote启动ActivityThread的具体方式,待后续再对代码进行深入研究
本篇主要分析的代码流程如下
- 在ActivityStarter对象的executeRequest函数中初始化ActivityRecord对象后,通过ActivityStack的startActivityLocked函数,将该ActivityRecord对象插入到ActivityStack对象的mWindowList的TOP位置保存
- 通过RootWindowContainer的resumeFocusedStacksTopActivities函数,调用到ActivityStack的resumeTopActivityUncheckedLocked函数,并最终调用ActivityStackSupervisor对象的startSpecificActivity函数
- 在startSpecificActivity函数中,通过ATMS的startProcessAsync函数,最终调用AMS.LocalService的startProcess函数,从而通过zygote进程初始化Launcher应用进程,并且通过ActivityThread入口启动Launcher应用的主界面
- ActivityThread是应用进程的入口,且每一个应用进程中都包含一个ActivityThread对象,当然此对象会在AMS中进行注册纳入管理