对于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