前言
熟悉Activity的啟動流程和運行原理是一個合格的應(yīng)用開發(fā)人員所應(yīng)該具備的基本素質(zhì),其重要程度就不多做描述了。同時,知識棧應(yīng)該不斷的更新,最新發(fā)布的Android 9.0版本相較于之前的幾個版本也做了許多改動和重構(gòu),但是大體流程變化不大。本文基于Android 9.0版本源碼,從Activity啟動方法startActivity為切入口分析整個流程。
相關(guān)類簡介
- Instrumentation
用于實現(xiàn)應(yīng)用程序測試代碼的基類。當(dāng)在打開儀器的情況下運行時,這個類將在任何應(yīng)用程序代碼之前為您實例化,允許您監(jiān)視系統(tǒng)與應(yīng)用程序的所有交互??梢酝ㄟ^AndroidManifest.xml的<Instrumentation>標(biāo)簽描述該類的實現(xiàn)。
- ActivityManager
該類提供與Activity、Service和Process相關(guān)的信息以及交互方法, 可以被看作是ActivityManagerService的輔助類。
- ActivityManagerService
Android中最核心的服務(wù),主要負(fù)責(zé)系統(tǒng)中四大組件的啟動、切換、調(diào)度及應(yīng)用程序的管理和調(diào)度等工作。
- ActivityThread
管理應(yīng)用程序進(jìn)程中主線程的執(zhí)行,根據(jù)Activity管理者的請求調(diào)度和執(zhí)行activities、broadcasts及其相關(guān)的操作。
- ActivityStack
負(fù)責(zé)單個Activity棧的狀態(tài)和管理。
- ActivityStackSupervisor
負(fù)責(zé)所有Activity棧的管理。內(nèi)部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個Activity棧。其中,mHomeStack管理的是Launcher相關(guān)的Activity棧;mFocusedStack管理的是當(dāng)前顯示在前臺Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前臺Activity的Activity棧。
- ClientLifecycleManager
用來管理多個客戶端生命周期執(zhí)行請求的管理類。
一、發(fā)出啟動請求
啟動一個Activity通常都是通過Activity的startActivity方法啟動。
frameworks/base/core/java/android/app/Activity.java
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
// Activity中的startActivity也是調(diào)用startActivityForResult方法來實現(xiàn)的,
// 當(dāng)startActivityForResult方法的requestCode為-1不返回結(jié)果,
// requestCode大于等于零則會回調(diào)Activity.onActivityResult方法返回結(jié)果。
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);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
之后Activity的startActivity方法會調(diào)用startActivityForResult方法來傳遞啟動請求,在startActivityForResult方法中如果是第一次啟動,mParent為空則會去調(diào)用Instrumentation.execStartActivity方法,否則調(diào)動Activity.startActivityFromChild方法。
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) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), 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;
}
二、ActivityManagerService接收并處理啟動請求
在Instrumentation.execStartActivity方法中看到了熟悉的身影ActivityManager,通過ActivityManager.getService()方法可以獲得ActivityManagerService提供的服務(wù),所以直接跳轉(zhuǎn)到ActivityManagerService.startActivity方法。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);
}
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivity");
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
ActivityManagerService.startActivity方法經(jīng)過多個方法調(diào)用會去執(zhí)行startActivityAsUser方法,在startActivityAsUser方法最后會通過ActivityStartController.obtainStarter方法獲得一個包含所有啟動信息的ActivityStarter對象并調(diào)用execute方法執(zhí)行。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup);
}
} finally {
onExecutionComplete();
}
}
因為在ActivityManagerService.startActivityAsUser中調(diào)用了ActivityStarter.setMayWait方法,所以這里 mRequest.mayWait值為true,會去調(diào)用startActivityMayWait方法。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
...
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup);
...
return res;
}
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup) {
...
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask, allowPendingRemoteAnimationRegistryLookup);
...
return getExternalResult(mLastStartActivityResult);
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
...
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
...
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
...
postStartActivityProcessing(r, result, mTargetStack);
return result;
}
ActivityStarter.startActivityMayWait方法中調(diào)用多個startActivity方法后會調(diào)用到一個比較重要的方法startActivityUnchecked。說它重要是因為這個方法里會根據(jù)啟動標(biāo)志位和Activity啟動模式來決定如何啟動一個Activity以及是否要調(diào)用deliverNewIntent方法通知Activity有一個Intent試圖重新啟動它。具體細(xì)節(jié)就不在這里分析了,感興趣的同學(xué)自行查看源碼體會一下吧。
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
...
ActivityRecord reusedActivity = getReusableIntentActivity();
...
if (reusedActivity != null) {
// When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
// still needs to be a lock task mode violation since the task gets cleared out and
// the device would otherwise leave the locked task.
if (mService.getLockTaskController().isLockTaskModeViolation(reusedActivity.getTask(),
(mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
return START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
// True if we are clearing top and resetting of a standard (default) launch mode
// ({@code LAUNCH_MULTIPLE}) activity. The existing activity will be finished.
final boolean clearTopAndResetStandardLaunchMode =
(mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
== (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
&& mLaunchMode == LAUNCH_MULTIPLE;
// If mStartActivity does not have a task associated with it, associate it with the
// reused activity's task. Do not do so if we're clearing top and resetting for a
// standard launchMode activity.
if (mStartActivity.getTask() == null && !clearTopAndResetStandardLaunchMode) {
mStartActivity.setTask(reusedActivity.getTask());
}
if (reusedActivity.getTask().intent == null) {
// This task was started because of movement of the activity based on affinity...
// Now that we are actually launching it, we can assign the base intent.
reusedActivity.getTask().setIntent(mStartActivity);
}
// This code path leads to delivering a new intent, we want to make sure we schedule it
// as the first operation, in case the activity will be resumed as a result of later
// operations.
if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| isDocumentLaunchesIntoExisting(mLaunchFlags)
|| isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
final TaskRecord task = reusedActivity.getTask();
// In this situation we want to remove all activities from the task up to the one
// being started. In most cases this means we are resetting the task to its initial
// state.
final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
mLaunchFlags);
// The above code can remove {@code reusedActivity} from the task, leading to the
// the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
// task reference is needed in the call below to
// {@link setTargetStackAndMoveToFrontIfNeeded}.
if (reusedActivity.getTask() == null) {
reusedActivity.setTask(task);
}
if (top != null) {
if (top.frontOfTask) {
// Activity aliases may mean we use different intents for the top activity,
// so make sure the task now has the identity of the new intent.
top.getTask().setIntent(mStartActivity);
}
deliverNewIntent(top);
}
}
mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);
reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);
final ActivityRecord outResult =
outActivity != null && outActivity.length > 0 ? outActivity[0] : null;
// When there is a reused activity and the current result is a trampoline activity,
// set the reused activity as the result.
if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
outActivity[0] = reusedActivity;
}
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do anything
// if that is the case, so this is it! And for paranoia, make sure we have
// correctly resumed the top activity.
resumeTargetStackIfNeeded();
return START_RETURN_INTENT_TO_CALLER;
}
if (reusedActivity != null) {
setTaskFromIntentActivity(reusedActivity);
if (!mAddingToTask && mReuseTask == null) {
// We didn't do anything... but it was needed (a.k.a., client don't use that
// intent!) And for paranoia, make sure we have correctly resumed the top activity.
resumeTargetStackIfNeeded();
if (outActivity != null && outActivity.length > 0) {
outActivity[0] = reusedActivity;
}
return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
}
}
}
if (mStartActivity.packageName == null) {
final ActivityStack sourceStack = mStartActivity.resultTo != null
? mStartActivity.resultTo.getStack() : null;
if (sourceStack != null) {
sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
null /* data */);
}
ActivityOptions.abort(mOptions);
return START_CLASS_NOT_FOUND;
}
// If the activity being launched is the same as the one currently at the top, then
// we need to check if it should only be launched once.
final ActivityStack topStack = mSupervisor.mFocusedStack;
final ActivityRecord topFocused = topStack.getTopActivity();
final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
if (dontStart) {
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do
// anything if that is the case, so this is it!
return START_RETURN_INTENT_TO_CALLER;
}
deliverNewIntent(top);
// Don't use mStartActivity.task to show the toast. We're not starting a new activity
// but reusing 'top'. Fields in mStartActivity may not be fully initialized.
mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
preferredLaunchDisplayId, topStack);
return START_DELIVERED_TO_TOP;
}
boolean newTask = false;
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// Should this be considered a new task?
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
} else if (mSourceRecord != null) {
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
result = setTaskFromInTask();
} else {
// This not being started from an existing activity, and not part of a new task...
// just put it in the top task, though these days this case should never happen.
setTaskToCurrentTopOrCreateNewTask();
}
if (result != START_SUCCESS) {
return result;
}
mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
mStartActivity.getTask().taskId);
}
ActivityStack.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
mTargetStack.mLastPausedActivity = null;
mSupervisor.sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);
mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
mOptions);
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mService.mWindowManager.executeAppTransition();
} else {
// If the target stack was not previously focusable (previous top running activity
// on that stack was not visible) then any prior calls to move the stack to the
// will not update the focused stack. If starting the new activity now allows the
// task stack to be focusable, then ensure that we now update the focused stack
// accordingly.
if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTask());
}
mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
preferredLaunchDisplayId, mTargetStack);
return START_SUCCESS;
}
無論以何種模式啟動最終都會調(diào)用ActivityStackSupervisor.resumeFocusedStackTopActivityLocked方法。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
...
return false;
}
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
result = resumeTopActivityInnerLocked(prev, options);
...
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, next, false);
}
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
return true;
}
在ActivityStack.resumeTopActivityInnerLocked方法中會去判斷是否有Activity處于Resume狀態(tài),如果有的話會先讓這個Activity執(zhí)行Pausing過程,然后再執(zhí)行startSpecificActivityLocked方法啟動要啟動Activity。此處分開兩段,先看一下棧頂Activity是如何退出的。
三、棧頂Activity執(zhí)行onPause方法退出
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean pauseImmediately) {
...
if (prev.app != null && prev.app.thread != null) {
try {
EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving);
mService.updateUsageStats(prev, false);
// Android 9.0在這里引入了ClientLifecycleManager和
// ClientTransactionHandler來輔助管理Activity生命周期,
// 他會發(fā)送EXECUTE_TRANSACTION消息到ActivityThread.H里面繼續(xù)處理。
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
...
}
在ActivityStack.startPausingLocked方法中通過ClientLifecycleManager的scheduleTransaction方法把PauseActivityItem事件加入到執(zhí)行計劃中,開始棧頂?shù)膒ausing過程。
frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
...
}
frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
ClientTransaction.schedule方法的mClient是一個IApplicationThread類型,ActivityThread的內(nèi)部類ApplicationThread派生這個接口類并實現(xiàn)了對應(yīng)的方法。所以直接跳轉(zhuǎn)到ApplicationThread中的scheduleTransaction方法。ActivityThread類中并沒有定義scheduleTransaction方法,所以調(diào)用的是他父類ClientTransactionHandler的scheduleTransaction方法。
frameworks/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
...
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
frameworks/base/core/java/android/app/ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
在ClientTransactionHandler.scheduleTransaction方法中調(diào)用了sendMessage方法,這個方法是一個抽象方法,其實現(xiàn)在ClientTransactionHandler派生類的ActivityThread中,ActivityThread.sendMessage方法會把消息發(fā)送給內(nèi)部名字叫H的Handler。
frameworks/base/core/java/android/app/ActivityThread.java
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1) {
sendMessage(what, obj, arg1, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2) {
sendMessage(what, obj, arg1, arg2, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
public void handleMessage(Message msg) {
...
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
...
break;
...
}
Handler H的實例接收到EXECUTE_TRANSACTION消息后調(diào)用TransactionExecutor.execute方法切換Activity狀態(tài)。TransactionExecutor.execute方法里面先執(zhí)行Callbacks,然后改變Activity當(dāng)前的生命周期狀態(tài)。此處由于沒有Callback所以直接跳轉(zhuǎn)executeLifecycleState方法。
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
...
}
public void executeCallbacks(ClientTransaction transaction) {
if (callbacks == null) {
// No callbacks to execute, return early.
return;
}
...
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
...
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
...
}
}
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
...
// Cycle to the state right before the final requested state.
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
在executeLifecycleState方法里面,會先去調(diào)用TransactionExecutor.cycleToPath執(zhí)行當(dāng)前生命周期狀態(tài)之前的狀態(tài),然后執(zhí)行ActivityLifecycleItem.execute方法。由于是從ON_RESUME狀態(tài)到ON_PAUSE狀態(tài)切換,中間沒有其他狀態(tài),cycleToPath這個情況下沒有做什么實質(zhì)性的事情,直接執(zhí)行execute方法。前面在ActivityStack.startPausingLocked方法里面scheduleTransaction傳遞的是PauseActivityItem對象,所以executeLifecycleState方法里調(diào)用的execute方法其實是PauseActivityItem.execute方法。
frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
...
client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
...
}
在PauseActivityItem.execute方法中調(diào)用ActivityThread.handlePauseActivity方法,經(jīng)過一步步調(diào)用來到performPauseActivity方法,在這個方法中會先去判斷是否需要調(diào)用callActivityOnSaveInstanceState方法來保存臨時數(shù)據(jù),然后執(zhí)行Instrumentation.callActivityOnPause方法繼續(xù)執(zhí)行pasue流程。
frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
...
performPauseActivity(r, finished, reason, pendingActions);
...
}
}
final Bundle performPauseActivity(IBinder token, boolean finished, String reason,
PendingTransactionActions pendingActions) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, reason, pendingActions) : null;
}
/**
* Pause the activity.
* @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.
*/
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {
...
if (shouldSaveState) {
callActivityOnSaveInstanceState(r);
}
performPauseActivityIfNeeded(r, reason);
...
return shouldSaveState ? r.state : null;
}
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
...
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException("Unable to pause activity "
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
}
}
r.setState(ON_PAUSE);
}
Instrumentation.callActivityOnPause方法中直接調(diào)用Activity.performPause,在performPause方法中我們終于看到了熟悉的身影Activity生命周期的onPause方法,至此棧頂Activity的Pausing流程全部完畢。
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
frameworks/base/core/java/android/app/Activity.java
final void performPause() {
...
onPause();
...
}
四、Activity所在的應(yīng)用進(jìn)程啟動過程
接下來分析一下應(yīng)用進(jìn)程的啟動過程,上面分析到ActivityStackSupervisor.startSpecificActivityLocked方法,在這個方法中會去根據(jù)進(jìn)程和線程是否存在判斷App是否已經(jīng)啟動,如果已經(jīng)啟動,就會調(diào)用realStartActivityLocked方法繼續(xù)處理。如果沒有啟動則調(diào)用ActivityManagerService.startProcessLocked方法創(chuàng)建新的進(jìn)程處理。接下來跟蹤一下一個新的Activity是如何一步步啟動的。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
...
if (app != null && app.thread != null) {
...
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
ActivityManagerService.startProcessLocked方法經(jīng)過多次跳轉(zhuǎn)最終會通過Process.start方法來為應(yīng)用創(chuàng)建進(jìn)程。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
private ProcessStartResult startProcess(String hostingType, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
...
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
...
}
frameworks/base/core/java/android/os/Process.java
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
frameworks/base/core/java/android/os/ZygoteProcess.java
public final Process.ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
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(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
boolean startChildZygote,
String[] extraArgs)
throws ZygoteStartFailedEx {
...
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
maybeSetApiBlacklistExemptions(primaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);
}
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
// The primary zygote didn't match. Try the secondary.
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
maybeSetApiBlacklistExemptions(secondaryZygoteState, false);
maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);
}
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
經(jīng)過一步步調(diào)用,可以發(fā)現(xiàn)其最終調(diào)用了Zygote并通過socket通信的方式讓Zygote進(jìn)程fork出一個新的進(jìn)程,并根據(jù)傳遞的”android.app.ActivityThread”字符串,反射出該對象并執(zhí)行ActivityThread的main方法對其進(jìn)行初始化。
五、Activity所在應(yīng)用主線程初始化
在ActivityThread.main方法中對ActivityThread進(jìn)行了初始化,創(chuàng)建了主線程的Looper對象并調(diào)用Looper.loop()方法啟動Looper,把自定義Handler類H的對象作為主線程的handler。接下來跳轉(zhuǎn)到ActivityThread.attach方法,看都做了什么。
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
...
Looper.prepareMainLooper();
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
Looper.loop();
...
}
六、啟動Activity
Activity所在的進(jìn)程創(chuàng)建完了,主線程也初始化了,接下來就該真正的啟動Activity了。在ActivityThread.attach方法中,首先會通過ActivityManagerService為這個應(yīng)用綁定一個Application,然后添加一個垃圾回收觀察者,每當(dāng)系統(tǒng)觸發(fā)垃圾回收的時候就會在run方法里面去計算應(yīng)用使用了多少內(nèi)存,如果超過總量的四分之三就會嘗試釋放內(nèi)存。最后,為根View添加config回調(diào)接收config變化相關(guān)的信息。
frameworks/base/core/java/android/app/ActivityThread.java
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
mSomeActivitiesChanged = false;
try {
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
});
}
...
ViewRootImpl.addConfigCallback(configChangedCallback);
}
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
...
}
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getChildAt(stackNdx);
if (!isFocusedStack(stack)) {
continue;
}
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.uid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ top.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
return didSomething;
}
在ActivityManagerService.attachApplication方法中經(jīng)過多次跳轉(zhuǎn)執(zhí)行到ActivityStackSupervisor.realStartActivityLocked方法??吹竭@個方法有沒有一點眼熟?沒錯,就是之前分析過程中遇到的如果應(yīng)用進(jìn)程已經(jīng)啟動的情況下去啟動Activity所調(diào)用的方法,有點繞,自己體會一下。在ActivityStackSupervisor.realStartActivityLocked方法中為ClientTransaction對象添加LaunchActivityItem的callback,然后設(shè)置當(dāng)前的生命周期狀態(tài),最后調(diào)用ClientLifecycleManager.scheduleTransaction方法執(zhí)行。
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
return true;
}
調(diào)用ClientLifecycleManager.scheduleTransaction方法之后具體是如何執(zhí)行的前面已經(jīng)分析過了,這里就不再分析了。先看一下執(zhí)行callback后跳轉(zhuǎn)到LaunchActivityItem.execute方法。
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
...
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}
frameworks/base/core/java/android/app/ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
經(jīng)過上面代碼一步步的跳轉(zhuǎn),執(zhí)行到ActivityThread.performLaunchActivity方法。在ActivityThread.performLaunchActivity方法中首先對Activity的ComponentName、ContextImpl、Activity以及Application對象進(jìn)行了初始化并相互關(guān)聯(lián),然后設(shè)置Activity主題,最后調(diào)用Instrumentation.callActivityOnCreate方法。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 初始化ComponentName
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
// 初始化ContextImpl和Activity
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
// 初始化Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
// Application、Activity和ContextImpl互相關(guān)聯(lián)
appContext.setOuterContext(activity);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
// 設(shè)置Activity的Theme
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
}
r.setState(ON_CREATE);
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
從Instrumentation.callActivityOnCreate方法繼續(xù)追蹤,跳轉(zhuǎn)到Activity.performCreate方法,在這里我們看到了Activity.onCreate方法。
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
...
activity.performCreate(icicle, persistentState);
...
}
frameworks/base/core/java/android/app/Activity.java
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
至此executeCallbacks執(zhí)行完畢,開始執(zhí)行executeLifecycleState方法。先執(zhí)行cycleToPath方法,生命周期狀態(tài)是從ON_CREATE狀態(tài)到ON_RESUME狀態(tài),中間有一個ON_START狀態(tài),所以會執(zhí)行ActivityThread.handleStartActivity方法。
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
private void cycleToPath(ActivityClientRecord r, int finish,
boolean excludeLastState) {
...
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path);
}
/** Transition the client through previously initialized state sequence. */
private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
log("Transitioning to state: " + state);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r.token, false /* show */,
0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}
從ActivityThread.handleStartActivity方法經(jīng)過多次跳轉(zhuǎn)最后會調(diào)用Activity.onStart方法,至此cycleToPath方法執(zhí)行完畢。
frameworks/base/core/java/android/app/ActivityThread.java
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions) {
...
// Start
activity.performStart("handleStartActivity");
r.setState(ON_START);
...
}
frameworks/base/core/java/android/app/Activity.java
final void performStart(String reason) {
...
mInstrumentation.callActivityOnStart(this);
...
}
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
執(zhí)行完畢cycleToPath,開始執(zhí)行ResumeActivityItem.execute方法。
frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
...
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
...
}
frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
// TODO Push resumeArgs into the activity for consideration
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
...
Looper.myQueue().addIdleHandler(new Idler());
...
}
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
...
try {
r.activity.onStateNotSaved();
r.activity.mFragments.noteStateNotSaved();
checkAndBlockForNetworkAccess();
if (r.pendingIntents != null) {
deliverNewIntents(r, r.pendingIntents);
r.pendingIntents = null;
}
if (r.pendingResults != null) {
deliverResults(r, r.pendingResults, reason);
r.pendingResults = null;
}
r.activity.performResume(r.startsNotResumed, reason);
r.state = null;
r.persistentState = null;
r.setState(ON_RESUME);
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException("Unable to resume activity "
+ r.intent.getComponent().toShortString() + ": " + e.toString(), e);
}
}
...
return r;
}
frameworks/base/core/java/android/app/Activity.java
final void performResume(boolean followedByPause, String reason) {
performRestart(true /* start */, reason);
...
// mResumed is set by the instrumentation
mInstrumentation.callActivityOnResume(this);
...
}
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
...
}
經(jīng)過上面的多次跳轉(zhuǎn)最終調(diào)用到Activity.onResume方法,Activity啟動完畢。
七、棧頂Activity執(zhí)行onStop過程
至此Activity的啟動流程基本上就分析完了,但是熟悉Activity生命周期的同學(xué)不難發(fā)現(xiàn),棧頂Activity執(zhí)行了onPause方法之后怎么沒有看到哪里執(zhí)行了onStop方法呢?之前在ActivityThread.handleResumeActivity方法里面有這么一行不起眼的代碼,當(dāng)MessageQueue空閑的時候就會執(zhí)行這個Handler。那什么時候空閑呢?從這行代碼所在的位置不難分析出是當(dāng)前Activity執(zhí)行完onResume的時候執(zhí)行。
frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
Looper.myQueue().addIdleHandler(new Idler());
...
}
接下來看一下Idler都做了什么。當(dāng)MessageQueue空閑的時候就會回調(diào)Idler.queueIdle方法,經(jīng)過層層調(diào)用跳轉(zhuǎn)到ActivityStack.stopActivityLocked方法。
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
...
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
...
return false;
}
}
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
synchronized (this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
ActivityRecord r =
mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
false /* processPausingActivities */, config);
if (stopProfiling) {
if ((mProfileProc == r.app) && mProfilerInfo != null) {
clearProfilerLocked();
}
}
}
}
Binder.restoreCallingIdentity(origId);
}
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
boolean processPausingActivities, Configuration config) {
...
// Stop any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = 0; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.getStack();
if (stack != null) {
if (r.finishing) {
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
"activityIdleInternalLocked");
} else {
stack.stopActivityLocked(r);
}
}
}
...
return r;
}
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
final void stopActivityLocked(ActivityRecord r) {
...
mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
StopActivityItem.obtain(r.visible, r.configChangeFlags));
...
}
在ActivityStack.stopActivityLocked方法中,又見到了ClientLifecycleManager.scheduleTransaction方法,前面已經(jīng)分析過多次,會去執(zhí)行StopActivityItem.execute方法,然后經(jīng)過多次跳轉(zhuǎn),最終執(zhí)行了Activity.onStop方法。至此,棧頂Activity的onStop過程分析完畢。
frameworks/base/core/java/android/app/servertransaction/StopActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
...
client.handleStopActivity(token, mShowWindow, mConfigChanges, pendingActions,
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
...
}
frameworks/base/core/java/android/app/ActivityThread.java
@Override
public void handleStopActivity(IBinder token, boolean show, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
...
performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
reason);
...
}
private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
boolean saveState, boolean finalStateRequest, String reason) {
...
if (!keepShown) {
callActivityOnStop(r, saveState, reason);
}
}
}
private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
...
try {
r.activity.performStop(false /*preserveWindow*/, reason);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to stop activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
...
}
frameworks/base/core/java/android/app/Activity.java
final void performStop(boolean preserveWindow, String reason) {
...
mInstrumentation.callActivityOnStop(this);
...
}
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnStop(Activity activity) {
activity.onStop();
}
總結(jié)
Activity的工作原理相對復(fù)雜,分析起來很有難度,往往一行不起眼的代碼都大有深意,在閱讀源碼過程中多次遇到分析不下去的情況,只能結(jié)合對Activity生命周期已有的認(rèn)知重頭來過查看漏了哪一處細(xì)節(jié),由結(jié)果反推過程也是一個很好的辦法。Android源碼解析之(十四)-->Activity啟動流程
和從應(yīng)用角度看Android源碼 - 是誰調(diào)用的ActivityThread的main方法
這兩篇文章也給了我很多啟發(fā),讓我多次找到回去的路。
Activity啟動流程:
1、應(yīng)用通過startActivity或是startActivityForResult方法向ActivityManagerService發(fā)出啟動請求。
2、ActivityManagerService接收到啟動請求后會進(jìn)行必要的初始化以及狀態(tài)的刷新,然后解析Activity的啟動模式,為啟動Activity做一系列的準(zhǔn)備工作。
3、做完上述準(zhǔn)備工作后,會去判斷棧頂是否為空,如果不為空即當(dāng)前有Activity顯示在前臺,則會先進(jìn)行棧頂Activity的onPause流程退出。
4、棧頂Activity執(zhí)行完onPause流程退出后開始啟動Activity。如果Activity被啟動過則直接執(zhí)行onRestart->onStart->onResume過程直接啟動Activity(熱啟動過程)。否則執(zhí)行Activity所在應(yīng)用的冷啟動過程。
5、冷啟動過程首先會通過Zygote進(jìn)程fork出一個新的進(jìn)程,然后根據(jù)傳遞的”android.app.ActivityThread”字符串,反射出該對象并執(zhí)行ActivityThread的main方法進(jìn)行主線程的初始化。
6、Activity所在應(yīng)用的進(jìn)程和主線程完成初始化之后開始啟動Activity,首先對Activity的ComponentName、ContextImpl、Activity以及Application對象進(jìn)行了初始化并相互關(guān)聯(lián),然后設(shè)置Activity主題,最后執(zhí)行onCreate->onStart->onResume方法完成Activity的啟動。
7、上述流程都執(zhí)行完畢后,會去執(zhí)行棧頂Activity的onStop過程。
至此,完整的Activity啟動流程全部執(zhí)行完畢。
參考文獻(xiàn)
Android源碼解析之(十四)-->Activity啟動流程
從應(yīng)用角度看Android源碼 - 是誰調(diào)用的ActivityThread的main方法