安卓12homeActivity的启动流程--第一次启动的是fallbackhome
然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合HomeItent的Activity,最终调用startHomeActivity()来启动Activity。obtainStarter() 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动,一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
...
// 启动Home Activity--Luncher
if (bootingSystemUser) {
// 通过ATM,启动Home Activity
t.traceBegin("startHomeOnAllDisplays");
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
t.traceEnd();
}
}
可以看到通过ATM启动启动Home Activity
追踪startHomeOnAllDisplays()会发现该方法位于frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java,是一个抽象方法,实际上mAtmInternal.startHomeOnAllDisplays()最终调用的是frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java的startHomeOnAllDisplays()方法。
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
//调用RootWindowContainer的startHomeOnAllDisplays(),最终到startHomeOnDisplay()
return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
}
}
该方法在Android 10中还位于RootActivityContainer下,而Android 11就位于RootWindowContainer下了,从这里也可以看出google最终的目的是把activity 和window融合。
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java下的startHomeOnAllDisplays()方法最终调用了startHomeOnDisplay()方法,该部分的调用链如下:
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) {
// 如果displayId无效,则回退到默认桌面
if (displayId == INVALID_DISPLAY) {
final Task rootTask = getTopDisplayFocusedRootTask();
displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY;
}
final DisplayContent display = getDisplayContent(displayId);
return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) ->
result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
allowInstrumenting, fromHomeKey),
false /* initValue */);
}
在安卓11以前,在startHomeOnDisplay()方法下就已经调用了启动Launch的startHomeActivity()了,安卓11又对startHomeActivity()做了一层封装,这层封装既startHomeOnTaskDisplayArea()方法,下面来探究一下该方法。
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {
...
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (taskDisplayArea == getDefaultTaskDisplayArea()) {
// 构建一个category为CATEGORY_HOME的Intent,表明是Home Activity
homeIntent = mService.getHomeIntent();
// 通过PMS从系统所用已安装的应用中,找到一个符合HomeItent的Activity
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
aInfo = info.first;
homeIntent = info.second;
}
...
// 启动Home Activity--Luncher
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
taskDisplayArea);
return true;
}
startHomeOnTaskDisplayArea()首先通过getHomeIntent()来构建一个category为CATEGORY_HOME的Intent,表明是Home Activity;然后通过resolveHomeActivity()从系统所用已安装的引用中,找到一个符合HomeItent的Activity,最终调用startHomeActivity()来启动Activity。
getHomeIntent()方法构建一个category为CATEGORY_HOME的Intent,表明是Home Activity。 Intent.CATEGORY_HOME = “android.intent.category.HOME” 这个category会在Launcher3的 AndroidManifest.xml中配置,表明是Home Acivity
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//不是生产模式,add一个CATEGORY_HOME
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
resolveHomeActivity()方法通过Binder跨进程通知PackageManagerService从系统所用已安装的引用中,找到一个符合HomeItent的Activity
ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
final int flags = ActivityManagerService.STOCK_PM_FLAGS;
//系统正常启动时,component为null
final ComponentName comp = homeIntent.getComponent();
ActivityInfo aInfo = null;
...
if (comp != null) {
// Factory test.
aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
} else {
//系统正常启动时,走该流程
final String resolvedType =
homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
//resolveIntent做了两件事:
// 1.通过queryIntentActivities来查找符合HomeIntent需求Activities
// 2.通过chooseBestActivity找到最符合Intent需求的Activity信息
final ResolveInfo info = AppGlobals.getPackageManager()
.resolveIntent(homeIntent, resolvedType, flags, userId);
if (info != null) {
aInfo = info.activityInfo;
}
}
...
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
return aInfo;
}
最后一步, mService.getActivityStartController().startHomeActivity这是调用了frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
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 root home task because when the
// foreground is standard type activity, the resolver activity should be put on the
// top of current foreground instead of bring root home task to front.
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
final int displayId = taskDisplayArea.getDisplayId();
options.setLaunchDisplayId(displayId);
options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken
.toWindowContainerToken());
// The home activity will be started later, defer resuming to avoid unnecessary operations
// (e.g. start home recursively) when creating root home task.
mSupervisor.beginDeferResume();
final Task rootHomeTask;
try {
// Make sure root home task exists on display area.
rootHomeTask = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
} finally {
mSupervisor.endDeferResume();
}
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
if (rootHomeTask.mInResumeTopActivity) {
// If we are in resume section already, home activity will be initialized, but not
// resumed (to avoid recursive resume) and will stay that way until something pokes it
// again. We need to schedule another resume.
mSupervisor.scheduleResumeTopActivities();
}
}
obtainStarter() 方法返回的是 ActivityStarter 对象,它负责 Activity 的启动,一系列 setXXX() 方法传入启动所需的各种参数,最后的 execute() 是真正的启动逻辑。
更多推荐
所有评论(0)