對於Activity的啓動可以觀看上一篇android啓動流程分析(二)進行查看下面分析activity的關閉流程如下圖:
看高清圖請下載
關閉activity的時候回調用finish方法代碼如下:
public void finish() {
finish(DONT_FINISH_TASK_WITH_ACTIVITY);
}
private void finish(int finishTask) {
if (mParent == null) {//
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
if (ActivityManagerNative.getDefault()
.finishActivity(mToken, resultCode, resultData, finishTask)) {//調用ActivityManagerService
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}
在這裏稍微解釋下mParent這個參數:Activity中存在父子Activity的關係。mParent參數是對那些在ActivityGroup中的Activity來說的。比如說在TabActivity中的Tab頁面裏嵌套的Activity,他們的mParent就是TabActivity。mParent的賦值在Activity.setParent(Activity
parent)方法中定義。大多數Activity.mParent爲空,因此此處直接往AMS.finishActivity流程走。這裏我們只分析沒有父類的,以及上父類的關閉原理也差不多。
對於ActivityManagerNative.getDefault().finishActivity(mToken, resultCode, resultData, finishTask)這句話實際就是調用了Ams裏面的finishActivity方法(爲什麼可以查看前面的文章android啓動流程分析(一)),直接查看Ams中的方法代碼如下:
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
......
try {
boolean res;
final boolean finishWithRootActivity =
finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
|| (finishWithRootActivity && r == rootR)) {
// If requested, remove the task that is associated to this activity only if it
// was the root activity in the task. The result code and data is ignored
// because we don't support returning them across task boundaries. Also, to
// keep backwards compatibility we remove the task from recents when finishing
// task with root activity.
res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
if (!res) {
Slog.i(TAG, "Removing task failed to finish activity");
}
} else {
res = tr.stack.requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true);//關閉activity
if (!res) {
Slog.i(TAG, "Failed to finish by app-request");
}
}
return res;
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
從上面的代碼可以看出這個關閉activity的語句調用的是ActivityStack類裏面的requestFinishActivityLocked方法,代碼如下:
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
Intent resultData, String reason, boolean oomAdj) {
......
finishActivityLocked(r, resultCode, resultData, reason, oomAdj);
return true;
}
final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData,
String reason, boolean oomAdj) {
......
if (mResumedActivity == r) {//當前activity關閉的時候調用
......
if (mPausingActivity == null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish needs to pause: " + r);
if (DEBUG_USER_LEAVING) Slog.v(TAG_USER_LEAVING,
"finish() => pause with userLeaving=false");
startPausingLocked(false, false, false, false);
}
if (endTask) {
mStackSupervisor.removeLockedTaskLocked(task);
}
} else if (r.state != ActivityState.PAUSING) {//不在暫停狀態的情況下調用
......
return finishCurrentActivityLocked(r, (r.visible || r.nowVisible) ?
FINISH_AFTER_VISIBLE : FINISH_AFTER_PAUSE, oomAdj) == null;
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + r);
}
return false;
}
如上面的代碼有兩個分支,我們是調用的activity的finish因此我們走的是第一種,調用了startPausingLocked方法代碼如下:
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
.....
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} 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;
}
.........
}
對於上面的prev.app.thread代表的是ActivityThread::ApplicationThread不明可以查看前面的文章(android啓動流程分析(一))schedulePauseActivity方法代碼如下:
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
+ " operation received seq: " + seq);
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
雖然上面的Message有兩種狀態但是最終調用的都是同一個方法代碼如下:
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
......
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
.....
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState, String reason) {
......
// Next have the activity save its current state and managed dialogs...
if (!r.activity.mFinished && saveState) {
callCallActivityOnSaveInstanceState(r);//調用activity的OnSaveInstanceState方法
}
performPauseActivityIfNeeded(r, reason);//調用activity的onpause方法
......
}
根據上面的代碼可知activity在沒有調用關閉以及saveState爲true(有AMS控制的)時候會調用OnSaveInstanceState方法,接下來調用onPause方法,進一步分析performPauseActivityIfNeeded代碼如下:
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
......
mInstrumentation.callActivityOnPause(r.activity);
......
r.paused = true;
}
調用了Activity類中的下面方法,上面調用的是Instrumentation類中的方法
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}
到這裏位置onPause方法就被調用了,接下來在ActivityThread這個類中的handlePauseActivity方法中來由一句話調用了代碼如下:
// Tell the activity manager we have paused.通過這意思是activity進入paused狀態的時候調用
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
對於ActivityManagerNative.getDefault().activityPaused(token);這句話一看就知道最終調用的是AMS中的activityPaused方法,此方法代碼如下:
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
接下來調用了ActivityStack類中的activityPausedLocked方法,代碼如下
private void completePauseLocked(boolean resumeNext) {
ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Complete pause: " + prev);
if (prev != null) {
final boolean wasStopping = prev.state == ActivityState.STOPPING;
prev.state = ActivityState.PAUSED;
if (prev.finishing) {//這個一般不不會調用之後再內存不足的時候纔會調用
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
} else if (prev.app != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
+ " wasStopping=" + wasStopping + " visible=" + prev.visible);
if (mStackSupervisor.mWaitingVisibleActivities.remove(prev)) {
if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
"Complete pause, no longer waiting: " + prev);
}
if (prev.deferRelaunchUntilPaused) {
// Complete the deferred relaunch that was waiting for pause to complete.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
relaunchActivityLocked(prev, prev.configChangeFlags, false,
prev.preserveWindowOnDeferredRelaunch);
} else if (wasStopping) {
// We are also stopping, the stop request must have gone soon after the pause.
// We can't clobber it, because the stop confirmation will not be handled.
// We don't need to schedule another stop, we only need to let it happen.
prev.state = ActivityState.STOPPING;
} else if ((!prev.visible && !hasVisibleBehindActivity())
|| mService.isSleepingOrShuttingDownLocked()) {
// If we were visible then resumeTopActivities will release resources before
// stopping.
addToStopping(prev, true /* immediate */);
}
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
prev = null;
}
// It is possible the activity was freezing the screen before it was paused.
// In that case go ahead and remove the freeze this activity has on the screen
// since it is no longer visible.
prev.stopFreezingScreenLocked(true /*force*/);
mPausingActivity = null;
}
if (resumeNext) {
......
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);//回覆前面的activy
......
}
......
}
在這裏調用resumeFocusedStackTopActivityLocked方法進行啓動上一個Activity代碼如下:
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.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
}
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
......
Bundle resumeAnimOptions = null;
if (anim) {
ActivityOptions opts = next.getOptionsForTargetActivityLocked();
if (opts != null) {
resumeAnimOptions = opts.toBundle();
}
next.applyOptionsLocked();
} else {
next.clearOptionsLocked();
}
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
......
try {
// Deliver all pending results.
ArrayList<ResultInfo> a = next.results;
if (a != null) {
final int N = a.size();
if (!next.finishing && N > 0) {
if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
"Delivering results to " + next + ": " + a);
next.app.thread.scheduleSendResult(next.appToken, a);
}
}
if (next.newIntents != null) {
next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
}
......
next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
mService.isNextTransitionForward(), resumeAnimOptions);
mStackSupervisor.checkReadyForSleepLocked();
.....
}
對於上面next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState, mService.isNextTransitionForward(), resumeAnimOptions);方法就是activity啓動的時候調用的一樣的可以參照上一篇文章(android啓動流程分析(二)),這裏面會調用onReStart-->onStart--->onResume生命週期我們在看看handleResumeActivity方法
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
......
// TODO Push resumeArgs into the activity for consideration
r = performResumeActivity(token, clearHide, reason);
......
if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(
TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
.....
}
通過上面的方法我們能看到在運行完performResumeActivity方法之後會執行Looper.myQueue().addIdleHandler(new Idler());可以查看Idler的類
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
if (a != null) {
mNewActivities = null;
IActivityManager am = ActivityManagerNative.getDefault();
ActivityClientRecord prev;
do {
if (localLOGV) Slog.v(
TAG, "Reporting idle of " + a +
" finished=" +
(a.activity != null && a.activity.mFinished));
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
ensureJitEnabled();
return false;
}
}
內部有一個queueIdle的回調方法,當它被添加到MessageQueue之後就會回調該方法,我們可以發現在這個方法體中調用了ActivityManagerNative.getDefault.activityIdle方法,通過之前的我們知道ActivityManagerNative.getDefault方法最終調用的是AMs中的方法activityIdle查看代碼如下:
@Override
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
.....
ActivityRecord r =
mStackSupervisor.activityIdleInternalLocked(token, false, config);//
.....
}
接下來調用下面方法ActivityStackSupervisor這個類中的方法
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
Configuration config) {
......
for (int i = 0; i < NS; i++) {
r = stops.get(i);
final ActivityStack stack = r.task.stack;
if (stack != null) {
if (r.finishing) {
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
} else {
stack.stopActivityLocked(r);
}
}
}
......
}
通過判斷語句可以知道如果要關閉就走第一條,否則就是進行stop狀態,查看一下finishCurrentActivityLocked方法如下(在ActivityStack中):
final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) {
......
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");
......
}
final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
......
try {
if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
r.configChangeFlags);
} catch (Exception e) {
// We can just ignore exceptions here... if the process
// has crashed, our death notification will clean things
// up.
//Slog.w(TAG, "Exception thrown during finish", e);
if (r.finishing) {
removeActivityFromHistoryLocked(
r, topTask, reason + " exceptionInScheduleDestroy");
removedFromHistory = true;
skipDestroy = true;
}
}
......
}
通過前面的分析r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,r.configChangeFlags);這就話實際上是調用了ActivityThread::ApplicationThread中的方法 private void handleDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance);
......
if (finishing) {
try {
ActivityManagerNative.getDefault().activityDestroyed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
......
r.activity.performStop(r.mPreserveWindow);
r.activity.mCalled = false;
mInstrumentation.callActivityOnDestroy(r.activity);
......
}
上面的方法在進一步分析就能知道剩下的聲明週期是onStop--->onDestory
總結:通過上一篇和這這一篇得出activity的啓動和關閉流程的生命週期的如下:
1、當啓動第一個Activity_A的時候的生命週期運行的方法:
onCreate--->onStart--->onPostCreate--->onResume--->onPostResume
這是鎖屏運行方法
onPause--->onSaveInstanceState--->onStop
開屏運行方法
onRestart--->onStart--->onResume--->onPostResume
2、在Activity_A中打開Activity_B的生命週期運行的方法:
A_onPause--->B_onCreate--->B_onStart--->B_onPostCreate--->B_onResume--->B_onPostResume--->A_onSaveInstanceState---->A_onStop
3、關閉Activity_B
B_onPause--->A_onRestart--->A_onStart--->A_onResume--->A_onPostResume--->B_onStop---->B_onDestroy