- SystemServer中使用AMS启动Launcher
- AMS调用 ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法
- 经历了ActivityStackSupervisor -> ActivityStack -> ActivityStackSupervisor ->AMS 的流程,期间处理了一些堆栈相关的工作,最终又回到了AMS
- AMS调用 ActivityStarter启动Launcher Activity
建议看完源码,回头看下时序图,会比较清晰
Android 10
时序图:
与安卓8一样从AMS启动,不同的是安卓10交给了一个ActivityTaskManagerInternal类型的服务mAtmInternal
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@VisibleForTesting
public ActivityTaskManagerInternal mAtmInternal;
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
…
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
…
t.traceBegin(“resumeTopActivities”);
mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
t.traceEnd();
…
}
我们看下mAtmInternal哪来的,LocalServices类里面是一个类与对象的键值对, 而ActivityTaskManagerInternal是一个抽象类,我们找到它的唯一继承类ActivityTaskManagerService.LocalService
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
RootActivityContainer mRootActivityContainer;
final class LocalService extends ActivityTaskManagerInternal {
@Override
public void resumeTopActivities(boolean scheduleIdle) {
synchronized (mGlobalLock) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
…
}
}
}
}
这里调用了RootActivityContainer的resumeFocusedStacksTopActivities方法
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean resumeFocusedStacksTopActivities() {
return resumeFocusedStacksTopActivities(null, null, null);
}
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
…
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
…
if (!resumedOnDisplay) {
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
return result;
}
老环节,接下来又走到了ActivityStack
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
…
result = resumeTopActivityInnerLocked(prev, options);
…
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
…
if (!hasRunningActivity) {
// There are no activities left in the stack, let’s look somewhere else.
return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
}
…
}
private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
ActivityOptions options) {
…
return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
}
resumeNextFocusableActivityWhenStackIsEmpty 方法又调用了RootActivityContainer的resumeHomeActivity
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
…
return startHomeOnDisplay(mCurrentUser, myReason, displayId);
}
boolean startHomeOnDisplay(int userId, String reason, int displayId) {
return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting /,
false / fromHomeKey */);
}
startHomeOnDisplay里面取到了homeIntent,然后我们看最后一行:
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
boolean fromHomeKey) {
…
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (displayId == DEFAULT_DISPLAY) {
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId);
aInfo = info.first;
homeIntent = info.second;
}
…
// 启动HomeActivity mService 是ActivityTaskManagerService
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
displayId);
return true;
}
mService.getActivityStartController()获取到的是ActivityStartController
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
private ActivityStartController mActivityStartController;
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController,
Looper looper) {
…
mActivityStartController = new ActivityStartController(this);
…
}
最后使用ActivityStartController来启动Launcher
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
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();
mLastHomeActivityStartRecord = tmpOutRecord[0];
…
if (homeStack.mInResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
结下来的流程就可以参考Activity的启动了
小结
- SystemServer中使用AMS启动Launcher
- AMS调用 ActivityTaskManagerInternal的resumeTopActivities方法
- 在 RootActivityContainer处理显示相关事情,然后使用ActivityStack处理了一些堆栈相关的工作,再回到RootActivityContainer
- 使用 ActivityStartController启动LauncherActivity
建议看完源码,回头看下时序图,会比较清晰
Android 11
时序图:
Android 11的Launcher启动其实跟Android 10差不多
与Android 10一样在AMS调用resumeTopActivities
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@VisibleForTesting
public ActivityTaskManagerInternal mAtmInternal;
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
…
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
…
t.traceBegin(“resumeTopActivities”);
mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
t.traceEnd();
…
}
不同的是,Android11使用了RootWindowContainer而不是RootActivityContainer来启动Launcher
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
RootWindowContainer mRootWindowContainer;
final class LocalService extends ActivityTaskManagerInternal {
@Override
public void resumeTopActivities(boolean scheduleIdle) {
synchronized (mGlobalLock) {
// 10为mRootActivityContainer
mRootWindowContainer.resumeFocusedStacksTopActivities();
if (scheduleIdle) {
mStackSupervisor.scheduleIdle();
}
}
}
}
}
后面的代码也有些差异,当ActivityDisplay里面不存在ActivityStack,即focusedStack == null 的时候,Android 11直接启动resumeHomeActivity方法
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedStacksTopActivities() {
return resumeFocusedStacksTopActivities(null, null, null);
}
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
…
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
…
if (!resumedOnDisplay) {
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetStack == null) {
result |= resumeHomeActivity(null /* prev */, “no-focusable-task”,
display.getDefaultTaskDisplayArea());
}
}
}
return result;
}
这段流程与安卓10差不多,使用ActivityStack处理
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
…
result = resumeTopActivityInnerLocked(prev, options);
…
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
…
if (!hasRunningActivity) {
// There are no activities left in the stack, let’s look somewhere else.
return resumeNextFocusableActivityWhenStackIsEmpty(prev, options);
}
…
}
private boolean resumeNextFocusableActivityWhenStackIsEmpty(ActivityRecord prev,
ActivityOptions options) {
…
return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
}
兜兜转转,最终又回到RootWindowContainer的resumeHomeActivity方法
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeHomeActivity(ActivityRecord prev, String reason,
TaskDisplayArea taskDisplayArea) {
if (!mService.isBooting() && !mService.isBooted()) {
// Not ready yet!
return false;
}
if (taskDisplayArea == null) {
taskDisplayArea = getDefaultTaskDisplayArea();
}
final ActivityRecord r = taskDisplayArea.getHomeActivity();
final String myReason = reason + " resumeHomeActivity";
// Only resume home activity if isn’t finishing.
if (r != null && !r.finishing) {
r.moveFocusableActivityToTop(myReason);
return resumeFocusedStacksTopActivities(r.getRootTask(), prev, null);
}
return startHomeOnTaskDisplayArea(mCurrentUser, myReason, taskDisplayArea,
false /* allowInstrumenting /, false / fromHomeKey */);
}
走到startHomeOnTaskDisplayArea方法(这个方法名跟之前不一样的)
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {
…
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (taskDisplayArea == getDefaultTaskDisplayArea()) {
homeIntent = mService.getHomeIntent();
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));
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);
mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, “startHomeActivity”);
}
final String myReason = reason + “:” + userId + “:” + UserHandle.getUserId(
aInfo.applicationInfo.uid) + “:” + taskDisplayArea.getDisplayId();
// 启动HomeActivity mService 是ActivityTaskManagerService
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
taskDisplayArea);
return true;
}
最后RootWindowContainer又使用ActivityStartControlle来启动,后面流程基本与Android 10 一样了,不(懒)做(得)赘(说)述(了)
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
private ActivityStartController mActivityStartController;
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController,
Looper looper) {
…
mActivityStartController = new ActivityStartController(this);
…
}
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
TaskDisplayArea taskDisplayArea) {
…
mSupervisor.beginDeferResume();
final ActivityStack homeStack;
try {
// Make sure home stack exists on display area.
homeStack = 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 (homeStack.mInResumeTopActivity) {
mSupervisor.scheduleResumeTopActivities();
}
}
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
小结
- 除了RootActivityContainer的工作替换给了RootWindowContainer,其他流程与安卓10变化不大
Launcher 启动Activity
Launcher通过startActivitySafely方法启动Activity packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
…
// 新任务栈启动
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
…
try {
…
startActivity(intent, optsBundle);
…
} catch (ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, “Unable to launch. tag=” + item + " intent=" + intent, e);
}
return false;
}
总结
最后
一线互联网Android面试题含详解(初级到高级专题)
这些题目是今年群友去腾讯、百度、小米、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。并且大多数都整理了答案,熟悉这些知识点会大大增加通过前两轮技术面试的几率
如果设置门槛,很多开发者朋友会因此错过这套高级架构资料,错过提升成为架构师的可能。这就失去了我们的初衷;让更多人都能通过高效高质量的学习,提升自己的技术和格局,升职加薪。
最后送给大家一句话,望共勉,永远不要放弃自己的梦想和追求;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
、小米、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。并且大多数都整理了答案,熟悉这些知识点会大大增加通过前两轮技术面试的几率
[外链图片转存中…(img-VToRZoe9-1714447257157)]
如果设置门槛,很多开发者朋友会因此错过这套高级架构资料,错过提升成为架构师的可能。这就失去了我们的初衷;让更多人都能通过高效高质量的学习,提升自己的技术和格局,升职加薪。
最后送给大家一句话,望共勉,永远不要放弃自己的梦想和追求;
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!