从源码角度看Activity生命周期

简介

Activity是几乎所有初级安卓程序员必学的一个知识点。我们都知道安卓最大的特色就是它能够呈现给用户界面,使用户能够与应用程序交互,这其中最重要的基本类就是各个Activity。然而,很多安卓开发者以为自己熟知了Activity的生命周期与launchMode等等知识点,就以为自己理解了它们。然而事实上并不,安卓源码中潜藏着十分复杂的逻辑支撑着Activity生命周期的变化。

本篇文章中,我将以源码的视角,分析Activity的每个生命周期的回调是如何被调用到的。同时,一些安卓framework的基本知识也会详细的讲讲。文章最后会留下几个有意义的问题,很值得我们去理解。

整体图

这张图虽然长的很像谷歌官方的那张图,但是的确是我自己画出来了的,和官方的图还是不太一样的。这里面的每个生命周期回调都会在下面的文章中分析到。

onCreate & onStart

启动一个Activity是整个生命周期最复杂的部分,这块老罗的书中就专门用了一章去讲。但我觉着我还是很有必要再用自己的语言去分析一遍,我认为就算看过老罗的那篇关于Activity的文章,再看我写的也是会有不少收获的~

App端调用

ContextImpl.java

1
2
3
4
5
6
7
8
9
@Override
public void startActivity(Intent intent, Bundle options) {
...
// 先获取到Instrumentation实例
// Instrumentation实例是在当前进程调用attach后,在bindApplication时初始化的
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}

关于ActivityThread的Instrumentation对象初始化,这方面以后我会单独写一篇在进程启动后,应用是如何绑定Application并初始化的分析。进程启动的源码分析,请看我的另一篇博客: 从源码角度看AMS.startProcessLocked

安卓中的双向bind call通信

Instrumentation.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// 获取到ApplicationThread binder call句柄,AMS调用调用它来通知ActivityThread onCreate服务端操作已经完成
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
...
// 获取与AMS binder call 通信的代理对象
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
...
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

安卓AMS核心组件中,最重要的两个binder接口当属IActivityManager和IApplicationThread了,App应用四大组件与AMS服务的双向通信基本仰仗着它们,以下作了个图方便理解:

main binder interface

  • ActivityManagerService继承自ActivityManagerNative, 为所有应用提供组件的服务;所有应用依靠ActivityManagerProxy代理对象调用接口
  • ApplicationThread是ActivityThread中一个内部类,它直接继承了ApplicationThreadNative对象,某种意义上来说是AMS的服务端。当AMS执行完操作时,依靠调用ApplicationThreadProxy的代理对象方法来通知应用完成余下的操作。

这样的设计在安卓系统中很通用,有一点需要额外留意的,大部分App调用到system_server端的接口是非ONEWAY的,也就是同步调用,应用需要等待system_server执行完成。大部分system_server调用到App端的接口是ONEWAY的,也就是异步调用,system_server的服务不需要等待应用完成操作。这样的设计保证了system_server不会收到App处理快慢的影响。

我个人认为,这样的设计其实是有弊端的。例如,如果system_server的某个服务接口调用耗时过久,并且持有了十分紧缺的AMS锁或者说PMS锁,那么其它调用很有可能需要等待这个锁。这样就导致了其它应用的调用等待时间长短会受到系统状况的影响。如果这个应用是前台应用,很有可能会导致ANR,直接影响到用户的使用体验。

因为这块实在是基础,所以谈的比较多。我们继续看Activity.onCreate的调用…

system_server端调用

ActivityManagerService.java

1
2
3
4
5
6
7
8
9
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
...
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}

ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
final 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 config,
Bundle options, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
...
// 从manifesst中获取Actiivty信息
// 这块需要调用到PMS的接口,关于PMS如何读取与解析manifest的中信息,后续会再进行分析
ActivityInfo aInfo =
resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
...
synchronized (mService) {
...
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
...
return res;
}
}
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode,
int callingPid, int callingUid, String callingPackage,
int realCallingPid, int realCallingUid, int startFlags, Bundle options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
ActivityContainer container, TaskRecord inTask) {
...
// 创建一个ActivityRecord
// AMS中,还存在着BroadcastRecord, ProcessRecord, ServiceRecord这些类,用于表示单个的组件记录
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, voiceSession != null, this, container, options);
...
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
...
return err;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
...
// 涉及到launchMode的逻辑
final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
...
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
...
return ActivityManager.START_SUCCESS;
}

这块的代码段其实特别长,涉及到stack的切换,还是挺复杂的。这块以后专门写一篇文章分析Activity launchMode机制。

ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
...
task.addActivityToTop(r);
task.setFrontOfTask();
r.putInHistory();
if (!isHomeStack() || numActivities() > 0) {
...
mWindowManager.addAppToken(task.mActivities.indexOf(r),
r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
...
if (r.mLaunchTaskBehind) {
// Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
// tell WindowManager that r is visible even though it is at the back of the stack.
mWindowManager.setAppVisibility(r.appToken, true);
ensureActivitiesVisibleLocked(null, 0);
} else if (SHOW_APP_STARTING_PREVIEW && doShow) {
...
mWindowManager.setAppStartingWindow(
r.appToken, r.packageName, r.theme,
mService.compatibilityInfoForPackageLocked(
r.info.applicationInfo), r.nonLocalizedLabel,
r.labelRes, r.icon, r.logo, r.windowFlags,
prev != null ? prev.appToken : null, showStartingIcon);
r.mStartingWindowShown = true;
}
} else {
// If this is the first activity, don't do any fancy animations,
// because there is nothing for it to animate on top of.
mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
(r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
...
}
...
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}

以上代码涉及到window apptoken, TaskRecord的操作,详细看的话篇幅很大,先略过…

ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
9
10
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
...
if (isFrontStack(targetStack)) {
// 将当前ActivityStack置顶
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
...
return result;
}

ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
...
try {
...
result = resumeTopActivityInnerLocked(prev, options);
}
...
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
...
// Find the first activity that is not finishing.
final ActivityRecord next = topRunningActivityLocked(null);
...
final TaskRecord prevTask = prev != null ? prev.task : null;
if (next == null) {
...
// 这里涉及到回到桌面的逻辑...
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
}
...
ActivityStack lastStack = mStackSupervisor.getLastStack();
if (next.app != null && next.app.thread != null) {
...
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
...
return true;
}

ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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) {
try {
...
// 先前的服务端操作已经完成,且应用进程已经存在,开始启动Activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
...
}
// 如果Activity所在进程未启动,则会先创建进程,再启动这个Activity
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}

此处,如果Activity所在进程不存在,则会先创建进程,然后再绑定Application,最后启动这个Activity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
...
// 更新进程的优先级
mService.updateLruProcessLocked(app, true, null);
mService.updateOomAdjLocked();
...
final ActivityStack stack = task.stack;
try {
...
app.forceProcessStateUpTo(mService.mTopProcessState);
// binder call 回到客户端
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
...
} catch (RemoteException e) {
...
}
...
return true;
}

到这里,Activity的创建在服务端就完成了,现在就是调用到客户端完成Activity的onCreate生命周期调用

ActivityThread.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
public void handleMessage(Message msg) {
...
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...å
// Initialize before creating the activity
WindowManagerGlobal.initialize();
Activity a = performLaunchActivity(r, customIntent);
...
}

在ActivityThread中,维护着一个名为H的Handler类,它会往主线程的消息队列中抛入事件。当system_server binder call到App端时,App的Binder线程并不会直接去做各种操作,而是向主线程队列中sendMessage,排队等待事件的派发。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
// 反射创建Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
...
try {
// 获取Application实例
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
Context appContext = createBaseContextForActivity(r, 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);
...
activity.mCalled = false;
// 此处调用Activity.onCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
if (!r.activity.mFinished) {
// 这里调用Activity.onStart方法
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
// 这里调用Activity.onRestroeInstanceState方法
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
// 调用Activity.onPostCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
...
}
}
...
} 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;
}

自此,从在客户端调用Context.startActivity到AMS执行各种操作最后到ActivityThread反射调用Activity的onCreate, onStart, onRestroeInstanceState, onPostCreate方法,Activity此时已经成功启动了。

onResume

ActivityThread.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 接上,此前Activity已经走完之前的生命周期
...
if (a != null) {
...
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
...
} else {
...
}
}
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
...
// TODO Push resumeArgs into the activity for consideration
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
...
// Tell the activity manager we have resumed.
if (reallyResume) {
try {
ActivityManagerNative.getDefault().activityResumed(token);
} catch (RemoteException ex) {
}
}
} else {
...
}
}
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide) {
ActivityClientRecord r = mActivities.get(token);
...
if (r != null && !r.activity.mFinished) {
if (clearHide) {
r.hideForNow = false;
r.activity.mStartedActivity = false;
}
try {
...
// Activity.onResume在这里被调用
r.activity.performResume();
EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED,
UserHandle.myUserId(), r.activity.getComponentName().getClassName());
r.paused = false;
r.stopped = false;
r.state = null;
r.persistentState = null;
} catch (Exception e) {
...
}
}
return r;
}

ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
@Override
public final void activityResumed(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized (this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
ActivityRecord.activityResumedLocked(token);
}
}
Binder.restoreCallingIdentity(origId);
}

ActivityRecord.java

1
2
3
4
5
6
static void activityResumedLocked(IBinder token) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (DEBUG_SAVED_STATE) Slog.i(TAG_STATES, "Resumed activity; dropping state of: " + r);
r.icicle = null;
r.haveState = false;
}

onPause

ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
12
13
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
...
if (pausing) {
...
if (next.app != null && next.app.thread != null) {
mService.updateLruProcessLocked(next.app, true, null);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
}
}

ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
boolean someActivityPaused = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFrontStack(stack) && stack.mResumedActivity != null) {
...
someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
dontWait);
}
}
}
return someActivityPaused;
}

ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
...
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) {
...
}
}
...
}

ActivityThread.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
...
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb());
...
}
}
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState) : null;
}
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState) {
...
try {
// Next have the activity save its current state and managed dialogs...
if (!r.activity.mFinished && saveState) {
// Activity.onSaveInstanceState周期
callCallActivityOnSaveInstanceState(r);
}
// Now we are idle.
r.activity.mCalled = false;
// Activity.onPause周期
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName());
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
...
return !r.activity.mFinished && saveState ? r.state : null;
}

onStop & onDestory

ActivityThread.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
...
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
...
if (!r.onlyLocalRequest) {
...
Looper.myQueue().addIdleHandler(new Idler());
}
...
}
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
...
if (a != null) {
mNewActivities = null;
IActivityManager am = ActivityManagerNative.getDefault();
ActivityClientRecord prev;
do {
...
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
// Ignore
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
...
return false;
}
}

ActivityManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
@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, config);
...
}
}
Binder.restoreCallingIdentity(origId);
}

ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
Configuration config) {
...
// Finish any activities that are scheduled to do so but have been
// waiting for the next one to start.
for (int i = 0; i < NF; i++) {
r = finishes.get(i);
final ActivityStack stack = r.task.stack;
if (stack != null) {
activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
}
}
...
return r;
}

ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) {
...
if (hadApp) {
...
try {
if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r);
r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
r.configChangeFlags);
} catch (Exception e) {
...
}
...
}
...
return removedFromHistory;
}

ActivityThread.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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) {
// If the system process has died, it's game over for everyone.
}
}
mSomeActivitiesChanged = true;
}
private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityClientRecord r = mActivities.get(token);
...
if (!r.stopped) {
try {
// Activity.onStop
r.activity.performStop();
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
...
try {
r.activity.mCalled = false;
// Activity.onDestroy
mInstrumentation.callActivityOnDestroy(r.activity);
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
}
...
return r;
}

Activity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
final void performStop() {
...
if (!mStopped) {
...
mFragments.dispatchStop();
mCalled = false;
mInstrumentation.callActivityOnStop(this);
...
}
mResumed = false;
}
final void performDestroy() {
mDestroyed = true;
mWindow.destroy();
mFragments.dispatchDestroy();
onDestroy();
mFragments.doLoaderDestroy();
if (mVoiceInteractor != null) {
mVoiceInteractor.detachActivity();
}
}

Instrumentation.java

1
2
3
4
5
6
7
8
public void callActivityOnStop(Activity activity) {
activity.onStop();
}
public void callActivityOnDestroy(Activity activity) {
activity.performDestroy();
...
}

总结

这篇文章我从源码角度跟踪了一遍Activity各种重要的生命周期回调是如何在framework中触发的。可以看见,Activity的核心操作主要还是在AMS中完成的,App客户端只是当system_server完成操作后,被通知调用回调的方法。可以说,不懂AMS管理WMS,ActivityRecord, TaskRecord的源码逻辑,只懂得Activity的生命周期顺序是不能够说自己懂Activity的。

Activity的生命周期涉及到安卓源码的基础,源码层次上,很多其它模块也是遵循着同样的规则。以下问题这篇文章没有包括,有兴趣的读者可以继续学习:

  • ActivityRecord与TaskRecord的关系?
  • ActivityStackSupervisor是如何管理ActivityStack的,安卓面试中常考的launchMode是如何实现的?
  • WMS与AMS是如何管理Activity生命周期与Window的呢?
  • Fragment的生命周期是如何随着Activity被管理的呢?
  • Activity与Service是如何实现绑定的呢?
扫码支持0.99元,您的支持将鼓励我继续创作!