问题背景
-
我们知道系统并没有直接提供启动进程的方式,总是有人发起调用(启动activity的时候会去判断相关进程在不在等流程)
-
Launcher
桌面本身是一个APP,当然也遵循普通APP进程的启动方式 -
通常分析普通进程都是从Launcher桌面上点击一个图标开始,那桌面是什么时候启动的呢?谁来启动的呢?
问题结论
在SystemServer
进程启动后,会去调用AMS
中的systemReady
进而启动 Launcher
。
在这里我们只梳理:从哪里开始触发 到 如何找到launcher的activity 即可,因为后续的流程相当于是走的普通activity启动流程。
过程分析
-
在
SystemServer
进程起来后,会去启动AMS
等相关服务 -
其中在
startOtherServices()
方法中,会去调用AMS#systemReady
-
在
AMS#systemReady
调用ATMS#startHomeOnAllDisplays
-
RootWindowContainer#startHomeOnDisplay
在这个方法中找到homeIntent
,最终调用atms
去启动这个intent
![](https://img.haomeiwen.com/i1319564/7f17bf579e4f788b.png)
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored and organized.
*/
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(() -> {
...
}, t);
....
}
/**
* Ready. Set. Go!
*/
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
....
synchronized (this) {
....
// Start up initial activity.
mBooting = true;
// Enable home activity for system user, so that the system can always boot. We don't
// do this when the system user is not setup since the setup wizard should be the one
// to handle home activity in this case.
if (SystemProperties.getBoolean(SYSTEM_USER_HOME_NEEDED, false)) {
t.traceBegin("enableHomeActivity");
ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
try {
AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
UserHandle.USER_SYSTEM, "am");
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
t.traceEnd();
}
boolean isBootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;
// Some systems - like automotive - will explicitly unlock system user then switch
// to a secondary user.
// TODO(b/266158156): this workaround shouldn't be necessary once we move
// the headless-user start logic to UserManager-land.
if (isBootingSystemUser && !UserManager.isHeadlessSystemUserMode()) {
t.traceBegin("startHomeOnAllDisplays");
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
t.traceEnd();
}
....
}
}
@Override
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
}
}
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 startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {
// Fallback to top focused display area if the provided one is invalid.
if (taskDisplayArea == null) {
final Task rootTask = getTopDisplayFocusedRootTask();
taskDisplayArea = rootTask != null ? rootTask.getDisplayArea()
: getDefaultTaskDisplayArea();
}
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (taskDisplayArea == getDefaultTaskDisplayArea()
|| mWmService.shouldPlacePrimaryHomeOnDisplay(
taskDisplayArea.getDisplayId(), userId)) {
// 去寻找 桌面的 intent
homeIntent = mService.getHomeIntent();
// 解析桌面activity的信息
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
aInfo = info.first;
homeIntent = info.second;
}
if (aInfo == null || homeIntent == null) {
return false;
}
if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) {
return false;
}
// Updates the home component of the intent.
homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
// 添加标志 FLAG_ACTIVITY_NEW_TASK
homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
// Updates the extra information of the intent.
if (fromHomeKey) {
homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
if (mWindowManager.getRecentsAnimationController() != null) {
mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart();
}
}
homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason);
// Update the reason for ANR debugging to verify if the user activity is the one that
// actually launched.
final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();
// 到这里就要去正常的调用 atms 去启动Activity流程
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
taskDisplayArea);
return true;
}
网友评论