android 4.2 launcher 源码,重拾Android-【吃透源码系列】之Android系统启动(七)Launcher的启动...

Launcher进程启动流程

android 4.2 launcher 源码,重拾Android-【吃透源码系列】之Android系统启动(七)Launcher的启动..._第1张图片

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>

pkgDataInfoMap,

@Nullable Map>

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>

pkgDataInfoMap,

@Nullable Map>

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连接,并把创建进程所需要的的参数传递过去。

你可能感兴趣的:(android,4.2,launcher,源码)