目录
  1. 1. Launcher进程启动流程
  2. 2. Launcher启动过程介绍
    1. 2.1. Launcher启动时序图
  3. 3. Android 11.0源码走读
  4. 4. Launcher启动流程关键类介绍
重拾Android-【吃透源码系列】之Android系统启动(七)Launcher的启动

Launcher进程启动流程

Launcher进程启动流程.png

Launcher启动过程介绍

SystemServer进程在启动的过程中会启动PackageManagerService,PKMS启动后会将系统中的应用程序安装完成。

Launcher启动时序图

Android 11.0源码走读

ActivityManagerService

/**
* Ready. Set. Go!
*/
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {

... 省略代码

// 在所有屏幕上开启桌面程序
if (bootingSystemUser) {
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
}

... 省略代码
}

查阅mAtmInternal对应的 ActivityTaskManagerInternal.java,这是一个抽象类,跟踪其继承者,可以发现其实现是 ATMS 的内部类 LocalService类

@Override
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
}
}

加锁交托给RootActivityContainer类,进而启动Launcher

RootActivityContainer

boolean startHomeOnAllDisplays(int userId, String reason) {
boolean homeStarted = false;
for (int i = getChildCount() - 1; i >= 0; i--) {
final int displayId = getChildAt(i).mDisplayId;
// 依次开启桌面程序
homeStarted |= startHomeOnDisplay(userId, reason, displayId);
}
return homeStarted;
}

boolean startHomeOnDisplay(int userId, String reason, int displayId) {
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
false /* fromHomeKey */);
}

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {

... 省略代码

result |= startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
allowInstrumenting, fromHomeKey);

... 省略代码

// 进入ActivityStartController控制类里进行Launcher应用启动
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
taskDisplayArea);

... 省略代码
}

boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {

... 省略代码

// 这里将调用PKMS查询符合Launcher应用条件的Activity Intent,这里先不考虑第二块屏幕
aInfo = resolveHomeActivity(userId, homeIntent);

... 省略代码

}

ActivityStartController

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
TaskDisplayArea taskDisplayArea) {

... 省略代码

// 构建者模式
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
// 继续跟踪代码
.execute();

... 省略代码
}

ActivityStarter.java

int execute() {
try {
...省略代码

res = executeRequest(mRequest);

...省略代码
} finally {
onExecutionComplete();
}
}

private int executeRequest(Request request) {

... 省略代码

mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
... 省略代码
}

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {

... 省略代码

result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
... 省略代码
}

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {

// 设置初始状态
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);

// 根据启动模式和Intent.flag 计算出该Activity所属的任务栈并加入,记住此时不会显示
computeLaunchingTaskFlags();

... 省略代码

// 进入 RootActivityContainer 执行 resumeFocusedStacksTopActivities(恢复)
mRootWindowContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);

... 省略代码
}

RootActivityContainer.resumeFocusedStacksTopActivities

boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

// 栈超级管理者判断是否恢复状态
if (!mStackSupervisor.readyToResume()) {
return false;
}

boolean result = false;
if (targetStack != null && (targetStack.isTopStackInDisplayArea()
|| getTopDisplayFocusedStack() == targetStack)) {
// 回到Activity管理栈对象
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}

... 省略代码
}

进入 ActivityStack.java


boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
... 省略代码

result = resumeTopActivityInnerLocked(prev, options);

... 省略代码
}

// 恢复顶部 Activity
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
... 省略代码

// 启动新Activity之前把当前可见的Activity暂停
pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);

... 省略代码

// 计算待启动的Activity所属进程是否存在
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
true /* activityChange */, false /* updateOomAdj */,
false /* addPendingTopUid */);
} else if (!next.isProcessRunning()) {
// Since the start-process is asynchronous, if we already know the process of next
// activity isn't running, we can start the process earlier to save the time to wait
// for the current activity to be paused.
final boolean isTop = this == taskDisplayArea.getFocusedStack();
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? "pre-top-activity" : "pre-activity");
}

... 省略代码

// Activity栈超级管理者启动指定Activity
mStackSupervisor.startSpecificActivity(next, true, true);

... 省略代码
}

继续 ActivityStackSupervisor.java 走起

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);

boolean knownToBeDead = false;
// 判断进程是否存在
if (wpc != null && wpc.hasThread()) {
try {
// 启动Activity
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}

// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}

r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

final boolean isTop = andResume && r.isTopRunningActivity();
// 通过ATMS中向 Handler 发送消息来异步创建进程,防止调用AMS出现死锁
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}

从上面最后一行代码可看出,和10.0相比,考虑到调用AMS服务出现死锁的问题,通过向Handler发送消息来启动进程

ActivityTaskManagerService.startProcessAsync代码如下:

void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
... 省略代码

final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);

... 省略代码
}

重点来看 ActivityManagerInternal::startProcess

进入 ActivityManagerInternal.java,发现startProcess方法是个抽象方法,这里利用归纳思想,一般源码后缀加上Internal标记内部类,其类内部抽象方法的实现一般都是在其去掉Internal的类里的LocalService内部类中。我们试一试,查找 ActivityManager,发现并没有,那与此极为相似的类还有哪些,ActivityManagerService?然后我们进入查找,Good job!找到了。挂一下源码继续分析

ActivityManagerService#LocalService

@Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {

... 省略代码
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) {

// 委托给 ProcessList 来负责进程的创建
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

boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
boolean mountExtStorageFull, String abiOverride) {

... 省略代码

// 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";

return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
instructionSet, invokeWith, startTime);

... 省略代码
}

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) {

... 省略代码

// 开启进程创建
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) {

... 省略代码

// 命中不同情境 zygote
// 这里直接进入AppZygote.java,看getProcess()
// 会返回与app zygote相关联的zygote进程(如果不在运行就会创建):ChildZygoteProcess -> ZygoteProcess 在此调用start函数
// 这个 entryPoint 参数至关重要,follow it
startResult = appZygote.getProcess().start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, app.info.packageName,
/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
false, false,
new String[]{PROC_START_SEQ_IDENT + app.startSeq});

... 省略代码
}

进入 ZygoteProcess.java

public final Process.ProcessStartResult start(@NonNull final String processClass,
final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>>
pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] zygoteArgs) {
// TODO (chriswailes): Is there a better place to check this value?
if (fetchUsapPoolEnabledPropWithMinInterval()) {
informZygotesOfUsapPoolStatus();
}

try {
// 从Zygote孵化开始一个新进程
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
bindMountAppStorageDirs, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}

private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
@Nullable final String niceName,
final int uid, final int gid,
@Nullable final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
boolean startChildZygote,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>>
pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
// args For Zygote
// 单独指出zygote进程参数包含entryPoint(android.app.ActivityThread)
argsForZygote.add(processClass);

// 加锁
synchronized(mLock) {
// The USAP pool can not be used if the application will not use the systems graphics
// driver. If that driver is requested use the Zygote application start path.
// 如果请求该驱动程序,需使用Zygote应用程序启动路径(也就是entryPoint)。
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
}

// 如果必须,尝试打开zygote的套接字
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
try {
// 将进程创建需要的信息通过socket发送过去,由zygote进程执行fork()指令
attemptConnectionToPrimaryZygote();

if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}

if (mZygoteSecondarySocketAddress != null) {
// The primary zygote didn't match. Try the secondary.
attemptConnectionToSecondaryZygote();

if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
}
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
}

throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}

Launcher启动流程关键类介绍

  • ActivityManagerService

Activity生命周期调度的服务类

  • ActivityTaskManagerService

剥离原先在AMS中有关Activity管理工作,到现有ATMS类中

  • RootActivityContainer

调用PKMS去查询手机系统中已安装的所有的应用,哪一个是符合launcher启动标准,去得到一个Intent对象,得到Intent对象之后交由ActivityStarter启动类进行进一步的启动工作。

  • ActivityStarter

做启动之前的各项检查,比如是否有在清单文件中注册,Activity是否有权限启动等等。

  • ActivityRecord

在Activity启动的时候,涉及到Activity进栈、出栈操作,这在服务端是拿不到Activity的实例的,因此ActivityRecord是在Server端对Activity的映射,里面记录了Activity的所有信息。

  • TaskRecord

任务栈,里面记录一个或多个ActivityRecord实例

  • ActivityStack

任务栈管理者角色,当一个应用运行时,可能有一个或者多个任务栈,这时该类作用就体现了,主要用来管理回退栈。

  • ActivityStackSupervisor

手机系统管理多个应用的任务栈超管角色: 管理多个ActivityStack对象。即管理Launcher和非launcher应用的ActivityStack实例。

  • ProcessList

把原先在AMS中有关启动进程的工作剥离至此

  • ZygoteProcess

建立起跟Zygote进程的socket连接,并把创建进程所需要的的参数传递过去。

打赏
  • 微信
  • 支付宝

评论