前言
Android10之前,在系統剛剛啟動之后,SystemServer進程的startBootstrapServices方法會啟動系統引導服務,像我們常接觸的ActivityManagerService、PowerManagerService、PackageManagerService等都是在這里啟動的,早期Activity的startActivity方法都是通過Instrumentation和ActivityManagerService做交互,但是隨著AMS的職責越來越多、代碼越來越龐大,在Android10以后,Google又對AMS做了進一步拆分,最終拆出來一個新的對象ActivityTaskManagerService,用來管理 Activity及其容器類,比如 Task、Stack、Display 等,以分擔AMS的部分職責。
一、Activity觸發ATMS執行startActivity方法的過程
1、時序圖
2、Activity的startActivity方法如下所示:
frameworks/base/core/java/android/app/Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback,
AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
...代碼省略...
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
startActivity方法會繼續調用startActivity(Intent intent, Bundle options),最終會繼續調用startActivityForResult方法。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
...代碼省略...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...代碼省略...
}
startActivityForResult方法會調用Instrumentation的execStartActivity方法。
3、Instrumentation 負責調用 Activity 和 Application 的生命周期,每個 Activity 都持有 Instrumentation 對象的一個引用,但是整個進程只會存在一個 Instrumentation 對象,Instrumentation的execStartActivity方法如下所示:
frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...代碼省略...
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
// 獲取 ActivityTaskManagerService 的代理對象
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
Instrumentation的execStartActivity方法會調用 ActivityTaskManager的getService方法會返回一個IActivityTaskManager類型的實例對象并調用該對象的startActivity方法。
4、在Android12源碼中并不存在IActivityTaskManager.java這樣一個文件,只能找到 IActivityTaskManager.aidl文件:
frameworks/base/core/java/android/app/IActivityTaskManager.aidl
interface IActivityManager {
int startActivity(in IApplicationThread caller, in String callingPackage,
in String callingFeatureId, in Intent intent, in String resolvedType,
in IBinder resultTo, in String resultWho, int requestCode,
int flags, in ProfilerInfo profilerInfo, in Bundle options);
}
我們知道源碼編譯的時候會將aidl文件轉化為 java 文件,IActivityTaskManager的startActivity方法的調用最終是通過binder來實現跨進程通信的。而IActivityTaskManager.aidl中startActivity方法的具體實現類,其實是ActivityTaskManagerService。
5、ActivityTaskManagerService的startActivity方法如下所示:
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
}
二、ATMS向AMS 發送創建應用進程的過程
1、時序圖和Activity任務棧
2、ActivityTaskManagerService的startActivity方法會進一步調用startActivityAsUser方法:
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
private ActivityStartController mActivityStartController;
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
// 檢查調用者的進程是否隔離,如果 isIsolated 則拋出 SecurityException 異常
assertPackageMatchesCallingUid(callingPackage);
// 檢查調用者權限,ATMS 根據傳入的 UserId 來確定調用者的權限
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
ActivityStartController getActivityStartController() {
return mActivityStartController;
}
}
3、startActivityAsUser方法最終會調用ActivityStartController的obtainStarter方法獲取ActivityStarter對象實例:
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
public class ActivityStartController {
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
}
4、獲取ActivityStarter對象之后會調用該對象的的setCaller、setCallingPackage等一系列方法進行參數設置,最后調用execute方法,相關方法的代碼如下所示:
class ActivityStarter {
//內部靜態類
static class Request {
private static final int DEFAULT_CALLING_UID = -1;
private static final int DEFAULT_CALLING_PID = 0;
static final int DEFAULT_REAL_CALLING_UID = -1;
static final int DEFAULT_REAL_CALLING_PID = 0;
IApplicationThread caller;
Intent intent;
NeededUriGrants intentGrants;
// A copy of the original requested intent, in case for ephemeral app launch.
Intent ephemeralIntent;
String resolvedType;
ActivityInfo activityInfo;
ResolveInfo resolveInfo;
IVoiceInteractionSession voiceSession;
IVoiceInteractor voiceInteractor;
IBinder resultTo;
String resultWho;
int requestCode;
int callingPid = DEFAULT_CALLING_PID;
int callingUid = DEFAULT_CALLING_UID;
String callingPackage;
@Nullable String callingFeatureId;
int realCallingPid = DEFAULT_REAL_CALLING_PID;
int realCallingUid = DEFAULT_REAL_CALLING_UID;
int startFlags;
SafeActivityOptions activityOptions;
boolean ignoreTargetSecurity;
boolean componentSpecified;
boolean avoidMoveToFront;
ActivityRecord[] outActivity;
Task inTask;
TaskFragment inTaskFragment;
String reason;
ProfilerInfo profilerInfo;
Configuration globalConfig;
int userId;
WaitResult waitResult;
int filterCallingUid;
PendingIntentRecord originatingPendingIntent;
boolean allowBackgroundActivityStart;
boolean allowPendingRemoteAnimationRegistryLookup;
Request() {
reset();
}
//為內部設置各種初始化參數
void reset() {
caller = null;
intent = null;
...代碼省略...
}
//更新參數
void set(@NonNull Request request) {
caller = request.caller;
intent = request.intent;
...代碼省略...
}
}
private final RootWindowContainer mRootWindowContainer;
Request mRequest = new Request();
ActivityStarter setCaller(IApplicationThread caller) {
mRequest.caller = caller;
return this;
}
ActivityStarter setCallingPackage(String callingPackage) {
mRequest.callingPackage = callingPackage;
return this;
}
int execute() {
try {
...代碼省略...
final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (rootTask != null) {
rootTask.mConfigWillChange = globalConfigWillChange;
}
...代碼省略...
res = executeRequest(mRequest); //執行請求操作
...代碼省略...
} finally {
onExecutionComplete();
}
}
}
這里省略了execute的大部分代碼,只保留了關鍵的一步,調用executeRequest方法:
private int executeRequest(Request request) {
...代碼省略...
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
...代碼省略...
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, restrictedBgActivity, intentGrants);
if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
}
return mLastStartActivityResult;
}
executeRequest方法會先將上面獲取的相關參數封裝成ActivityRecord對象,該對象內部記錄了Activity的所有信息,然后會調用startActivityUnchecked方法:
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
...代碼省略...
try {
mService.deferWindowLayout();
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
...代碼省略...
} finally {
...代碼省略...
}
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
}
startActivityUnchecked方法會進一步調用startActivityInner方法:
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
...代碼省略...
// 因為可能會復用已經存在的頁面棧而導致棧順序發生變化,這里要獲取頂部的頁面棧
final Task prevTopTask = mPreferredTaskDisplayArea.getFocusedRootTask();
final Task reusedTask = getReusableTask();
...代碼省略...
if (mDoResume) {
final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
if (!mTargetRootTask.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
mTargetRootTask.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
mTargetRootTask.mDisplayContent.executeAppTransition();
} else {
if (mTargetRootTask.isTopActivityFocusable()
&& !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
mTargetRootTask.moveToFront("startActivityInner");
}
//調用RootWindowContainer的resumeFocusedTasksTopActivities方法
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
}
mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
// Update the recent tasks list immediately when the activity starts
mSupervisor.mRecentTasks.add(startedTask);
mSupervisor.handleNonResizableTaskIfNeeded(startedTask,
mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
return START_SUCCESS;
}
主要就是處理 Activity 的啟動模式有關的邏輯,處理已經存在的任務棧,最后會調用RootWindowContainer的resumeFocusedTasksTopActivities方法。
5、RootWindowContainer是窗口容器(WindowContainer)的根容器,管理所有的窗口容器,設備上所有的窗口(Window)、顯示屏幕(Display)都是由它來管理的。RootWindowContainer的resumeFocusedTasksTopActivities方法如下所示:
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
class RootWindowContainer extends WindowContainer<DisplayContent>
implements DisplayManager.DisplayListener {
boolean resumeFocusedTasksTopActivities(
Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
boolean deferPause) {
...代碼省略...
boolean result = false;
if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
|| getTopDisplayFocusedRootTask() == targetRootTask)) {
result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
deferPause);
}
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
final DisplayContent display = getChildAt(displayNdx);
final boolean curResult = result;
boolean[] resumedOnDisplay = new boolean[1];
display.forAllRootTasks(rootTask -> {
final ActivityRecord topRunningActivity = rootTask.topRunningActivity();
if (!rootTask.isFocusableAndVisible() || topRunningActivity == null) {
return;
}
if (rootTask == targetRootTask) {
// Simply update the result for targetRootTask because the targetRootTask
// had already resumed in above. We don't want to resume it again,
// especially in some cases, it would cause a second launch failure
// if app process was dead.
resumedOnDisplay[0] |= curResult;
return;
}
if (rootTask.getDisplayArea().isTopRootTask(rootTask)
&& topRunningActivity.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront
// operation, but only consider the top task and root-task on that
// display.
rootTask.executeAppTransition(targetOptions);
} else {
resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);
}
});
result |= resumedOnDisplay[0];
if (!resumedOnDisplay[0]) {
//獲取當前屏幕設備的焦點任務棧
final Task focusedRoot = display.getFocusedRootTask();
if (focusedRoot != null) {
//如果焦點任務棧不為空則喚醒頂部的Activity
result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
} else if (targetRootTask == null) {
//否則喚醒首頁Activity
result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
display.getDefaultTaskDisplayArea());
}
}
}
return result;
}
}
resumeFocusedTasksTopActivities方法會恢復對應任務棧頂部的 Activity,如果沒有合法的Activity則恢復首頁Activity,如果有合法的Activity,則調用Task對象的resumeTopActivityUncheckedLocked方法來繼續啟動流程。
6、Task用來描述一個Activity任務棧,Task的resumeTopActivityUncheckedLocked方法如下所示:
frameworks/base/services/core/java/com/android/server/wm/Task.java
class Task extends TaskFragment {
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
return resumeTopActivityUncheckedLocked(prev, options, false /* skipPause */);
}
}
resumeTopActivityUncheckedLocked內部直接調用了同名但參數不同的另一個方法:
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) {
if (mInResumeTopActivity) {
return false;
}
boolean someActivityResumed = false;
try {
mInResumeTopActivity = true;
if (isLeafTask()) {
if (isFocusableAndVisible()) {
//繼續調用resumeTopActivityInnerLocked方法
someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
}
} else {
int idx = mChildren.size() - 1;
while (idx >= 0) {
final Task child = (Task) getChildAt(idx--);
if (!child.isTopActivityFocusable()) {
continue;
}
if (child.getVisibility(null /* starting */)
!= TASK_FRAGMENT_VISIBILITY_VISIBLE) {
break;
}
someActivityResumed |= child.resumeTopActivityUncheckedLocked(prev, options, deferPause);
if (idx >= mChildren.size()) {
idx = mChildren.size() - 1;
}
}
}
final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return someActivityResumed;
}
該方法內部會進行一系列條件判斷,最終會繼續調用resumeTopActivityInnerLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
if (!mAtmService.isBooting() && !mAtmService.isBooted()) {
// Not ready yet!
return false;
}
//獲取當前頂部正在運行的Activity
final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);
if (topActivity == null) {
// There are no activities left in this task, let's look somewhere else.
//如果根任務棧為空則返回下一個焦點Activity
return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);
}
final boolean[] resumed = new boolean[1];
//獲取當前頂部正在運行的Activity的TaskFragment
final TaskFragment topFragment = topActivity.getTaskFragment();
//喚醒
resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);
forAllLeafTaskFragments(f -> {
if (topFragment == f) {
return;
}
if (!f.canBeResumed(null /* starting */)) {
return;
}
resumed[0] |= f.resumeTopActivity(prev, options, deferPause);
}, true);
return resumed[0];
}
resumeTopActivityInnerLocked會調用父類TaskFragment的一個關鍵方法resumeTopActivity來繼續喚醒頂部Activity。
7、TaskFragment的resumeTopActivity方法如下所示:
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...代碼省略...
//進程存在
if (next.attachedToProcess()) {
...代碼省略...
try {
next.completeResumeLocked();
} catch (Exception e) {
...代碼省略...
}
} else {//進程不存在
...代碼省略...
mTaskSupervisor.startSpecificActivity(next, true, true);
}
return true;
}
由于前面已經將對應 Activity 的 ActivityRecord 添加到了棧頂,所以resumeTopActivity方法恢復的就是即將啟動的棧頂 Activity,該方法中做了一系列判斷,確保待啟動 Activity 可見性、預定 Activity 的切換動畫等。然后會判斷將要啟動的Activity進程是否存在,如果存在則會調用ActivityRecord的completeResumeLocked方法:
void completeResumeLocked() {
final boolean wasVisible = mVisibleRequested;
setVisibility(true);
if (!wasVisible) {
// Visibility has changed, so take a note of it so we call the TaskStackChangedListener
mTaskSupervisor.mAppVisibilitiesChangedSinceLastPause = true;
}
idle = false;
results = null;
if (newIntents != null && newIntents.size() > 0) {
mLastNewIntent = newIntents.get(newIntents.size() - 1);
}
newIntents = null;
stopped = false;
if (isActivityTypeHome()) {
mTaskSupervisor.updateHomeProcess(task.getBottomMostActivity().app);
}
if (nowVisible) {
mTaskSupervisor.stopWaitingForActivityVisible(this);
}
// Schedule an idle timeout in case the app doesn't do it for us.
mTaskSupervisor.scheduleIdleTimeout(this);
mTaskSupervisor.reportResumedActivityLocked(this);
resumeKeyDispatchingLocked();
final Task rootTask = getRootTask();
mTaskSupervisor.mNoAnimActivities.clear();
returningOptions = null;
if (canTurnScreenOn()) {
mTaskSupervisor.wakeUp("turnScreenOnFlag");
} else {
// If the screen is going to turn on because the caller explicitly requested it and
// the keyguard is not showing don't attempt to sleep. Otherwise the Activity will
// pause and then resume again later, which will result in a double life-cycle event.
rootTask.checkReadyForSleep();
}
}
則會調用
7、Task是一個管理類,用來管理系統所有Activity,其內部維護了Activity的所有狀態、特殊狀態的Activity以及和Activity相關的列表等數據,Task