Android Framework(五)——Activity生命周期分析

在系列第二篇文章中我们知道了Activity的整个启动流程,知道Activity是在App接收到启动Activity请求时通过反射的方式创建,在创建之后紧接着就会回调其生命周期。

本篇文章将会从Activity#attach开始,分析Activity在各个生命周期阶段的主要工作。

初始化阶段

通过之前的文章,Activity的创建由ActivityThread的performLaunchActivity来完成,在创建完成后首先会调用其attach方法将一些数据与Activity进行绑定,来看看attach方法:

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
@UnsupportedAppUsage
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
attachBaseContext(context);

// 为FragmentManager绑定Controller
mFragments.attachHost(null /*parent*/);

// 创建Window,并初始化
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}

// 初始化一些变量
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mAssistToken = assistToken;
mIdent = ident;
mApplication = application;
mIntent = intent;
mReferrer = referrer;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;

···

// 为Window绑定WindowManager
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

···
}

attach方法为Activity注入外部环境的一些对象,其中为Activity创建了Window。

Create阶段

执行完attach方法后,ActivityThread将会调用Instrumentation中的callActivityOnCreate方法来开启Activity的Create阶段:

1
mInstrumentation.callActivityOnCreate(activity, r.state);

这里会分为三个步骤:

  • prePerformCreate:执行在Activity#onCreate之前,完成一些预处理
  • performCreate:回调Activity#onCreate方法
  • postPerformCreate:执行在Activity#onCreate之后,完成一些收尾工作

Instrumentation#prePerformCreate

此方法用于将同步启动的Activity从列表mWaitingActivities中移除。

同步启动是指使用Instrumentation#startActivitySync方法启动的Activity,使用此方法启动Activity会同步执行到Activity成功运行才会返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void prePerformCreate(Activity activity) {
if (mWaitingActivities != null) {
synchronized (mSync) {
final int N = mWaitingActivities.size();
for (int i=0; i<N; i++) {
final ActivityWaiter aw = mWaitingActivities.get(i);
final Intent intent = aw.intent;
if (intent.filterEquals(activity.getIntent())) {
aw.activity = activity;
mMessageQueue.addIdleHandler(new ActivityGoing(aw));
}
}
}
}
}

可以看到,所谓的“Activity成功运行”其实就是在create阶段中,不过这里并不会确保在prePerformCreate执行后就立即解除阻塞状态,因为这里用的是IdleHandler。

Activity#performCreate

此部分将会真正回调Activity的onCreate方法。

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
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}

@UnsupportedAppUsage
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
// 分发preCreated事件
dispatchActivityPreCreated(icicle);
mCanEnterPictureInPicture = true;
// 恢复权限相关标志变量
restoreHasCurrentPermissionRequest(icicle);
// 回调onCreate
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}

// 恢复转场动画相关
mActivityTransitionState.readState(icicle);

mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);

// 通知fragment分发create事件
mFragments.dispatchActivityCreated();
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
// 分发postCreated事件
dispatchActivityPostCreated(icicle);
}

可以看到这里除了回调Activity的onCreate生命周期回调外,还会通知FragmentManager分发onActivityCreated事件,以及调用ActivityLifecycleCallback中的切面方法。

Activity#onCreate

onCreate方法中主要是对于异常重启的Activity恢复一些数据,然后调用dispatchActivityCreated来回调所有ActivityLifecycleCallback。

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
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (mLastNonConfigurationInstances != null) {
mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
}
if (mActivityInfo.parentActivityName != null) {
if (mActionBar == null) {
mEnableDefaultActionBarUp = true;
} else {
mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
}
}
if (savedInstanceState != null) {
mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
View.LAST_APP_AUTOFILL_ID);

if (mAutoFillResetNeeded) {
getAutofillManager().onCreate(savedInstanceState);
}

Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.fragments : null);
}
mFragments.dispatchCreate();
dispatchActivityCreated(savedInstanceState);
if (mVoiceInteractor != null) {
mVoiceInteractor.attachActivity(this);
}
mRestoredFromBundle = savedInstanceState != null;
mCalled = true;
}

Instrumentation#postPerformCreate

此方法是Instrumentation.postPerformCreate所做工作是一致的,主要是保证Activity从列表mWaitingActivities中移除。

Start阶段

执行完ActivityThread中的performLaunchActivity方法之后,Activity就已经被成功启动,不过此时Activity还处于ON_CREATE状态,而我们是希望此Activity的目标状态(Target State)是ON_RESUME,那么我们还需要顺序的执行Activity的生命周期回调onStart和onResume。

执行完LaunchActivity这个事务后,TransactionExecutor会帮我们平滑的将Activity的生命周期执行到Target State。主要是在cycleToPath方法中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
// 当前生命周期,ON_CREATE
final int start = r.getLifecycleState();
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Cycle activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " from: " + getStateName(start) + " to: " + getStateName(finish)
+ " excludeLastState: " + excludeLastState);
}

// finish表示Target State,本次流程为ON_RESUME
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path, transaction);
}

cycleToPath计算了我们的起始阶段和终止阶段,并且调用了TransactionExecutorHelper中的getLifecyclePath得到了一个IntArray path,并将path传递给了performLifecycleSequence方法,此IntArray中存储了需要顺序执行的生命周期。

performLifecycleSequence方法负责根据path来调用ClientTransactionHandler中的具体方法,代码如下:

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
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Transitioning activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " to state: " + getStateName(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);
}
}
}

代码很简单,就是根据path中的值来调用ClientTransactionHandler中的对应方法。

本次流程中,目前Activity的状态是ON_START,那么将会调用ClientTransactionHandler中的handleStartActivity方法。

前面文章已经说过,ClientTransactionHandler的实现类就是ActivityThread,我们来看方法的源码。

ActivityThread#handleStartActivity

与handleLaunchActivity方法类似,handleStartActivity用于处理Activity的ON_START生命周期,其中就会回调Activity的onStart方法。

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
@Override
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions) {
final Activity activity = r.activity;
if (r.activity == null) {
return;
}
if (!r.stopped) {
throw new IllegalStateException("Can't start activity that is not stopped.");
}
if (r.activity.mFinished) {
return;
}

// activity的start生命周期工作
activity.performStart("handleStartActivity");
r.setState(ON_START);

if (pendingActions == null) {
return;
}

// 处理Activity的重启恢复数据
// 调用onRestoreInstanceState恢复数据
if (pendingActions.shouldRestoreInstanceState()) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {

mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}

// 调用Activity.onPostCreate()方法
if (pendingActions.shouldCallOnPostCreate()) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString()
+ " did not call through to super.onPostCreate()");
}
}
}

可以看到此阶段除了要执行Activity的performStart方法处理ON_START状态之外,还会考虑是否要调用onRestoreInstanceState来恢复数据,之后会调用Activity的onPostCreate方法,此方法我们通常不会去重写它,主要是通知系统相关类来完成初始化。

Activity#performStart

performStart方法与performCreate方法类似,主要是分发preStart事件、调用onStart、分发postStart事件。

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
final void performStart(String reason) {
dispatchActivityPreStarted();
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
mFragments.noteStateNotSaved();
mCalled = false;
mFragments.execPendingActions();
// 调用onStart回调
mInstrumentation.callActivityOnStart(this);
writeEventLog(LOG_AM_ON_START_CALLED, reason);

if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStart()");
}
mFragments.dispatchStart();
mFragments.reportLoaderStart();

boolean isAppDebuggable =
(mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;

// This property is set for all non-user builds except final release
boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1;

// 对于Debug包会弹出一个Debuggable的提示
if (isAppDebuggable || isDlwarningEnabled) {
String dlwarning = getDlWarning();
if (dlwarning != null) {
String appName = getApplicationInfo().loadLabel(getPackageManager())
.toString();
String warning = "Detected problems with app native libraries\n" +
"(please consult log for detail):\n" + dlwarning;
if (isAppDebuggable) {
new AlertDialog.Builder(this).
setTitle(appName).
setMessage(warning).
setPositiveButton(android.R.string.ok, null).
setCancelable(false).
show();
} else {
Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show();
}
}
}

GraphicsEnvironment.getInstance().showAngleInUseDialogBox(this);

mActivityTransitionState.enterReady(this);
dispatchActivityPostStarted();
}

Activity的onStart回调通过Instrumentation来执行,来看看onStart源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@CallSuper
protected void onStart() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStart " + this);
mCalled = true;

// 执行Loader的start方法
mFragments.doLoaderStart();

// 分发start事件
dispatchActivityStarted();

if (mAutoFillResetNeeded) {
getAutofillManager().onVisibleForAutofill();
}
}

Resume阶段

由于我们的Activity目标状态为ON_RESUME,因此执行完handleStartActivity方法后,将会继续执行handleResumeActivity方法。

ActivityThread#handleResumeActivity

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
// 在后台时可能发送了gcIdler,这里取消掉
unscheduleGcIdler();

// 这个值在之前gcWatch里面有用到,为true时会才会考虑回收Activity
mSomeActivitiesChanged = true;

// 处理生命周期到onResume
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r == null) {
return;
}
if (mActivitiesToBeDestroyed.containsKey(token)) {
// 对于马上要destroy的Activity,后续操作已经无意义
return;
}

final Activity a = r.activity;

final int forwardBit = isForward
? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

// 在调用startActivity后mStartedActivity会置为true
// 当我们在resume之前调用了startActivity,那么此Activity不应该显示
// 而是应该显示最新启动的Activity
boolean willBeVisible = !a.mStartedActivity;
if (!willBeVisible) {
try {
// 跟ATMS再确认一次
willBeVisible = ActivityTaskManager.getService().willActivityBeVisible(
a.getActivityToken());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

// window还未被添加到WindowManager同时Activity是需要显示的
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// 对于复用decorView,通知ViewRoot
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 将decorView添加到WindowManager
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}

} else if (!willBeVisible) {
if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
}

// Get rid of anything left hanging around.
cleanUpPendingRemoveWindows(r, false /* force */);

// 当前window确定是要显示的
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {

// onConfigurationChanged方法在此处被调用
performConfigurationChangedForActivity(r, r.newConfig);
r.newConfig = null;
}

WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();

// 更新DecorView的LayoutParams
wm.updateViewLayout(decor, l);
}
}

···
}

handleResumeActivity方法会判断此Activity的Window是否已经添加到WindowManager中,以及是否是真正需要显示的。如果是要显示的并且还未添加,那么将会调用WindowManager的addView方法来讲将decor添加到WindowManager中,这是Resume阶段的关键方法,来看一下。

WindowManagerImpl#addView

WindowManager是一个接口,其实现类为WindowManagerImpl,来看看addView方法源码。

frameworks/base/core/java/android/view/WindowManagerImpl.java

1
2
3
4
5
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}

此处调用了两个方法,applyDefaultToken方法中会检测传入的LayoutParams必须为WindowManager.LayoutParams,否则会直接抛异常。另外如果当前Window没有父Window,这意味这它的token有可能为null,此时会将其赋值为默认的token。

接下来调用了WindowManagerGlobal中的addView方法。

WindowManagerGlobal#addView

WindowManagerGlobal是一个全局的单例对象,其代理了WindowManagerImpl中的一些与上下文Context无关的方法,负责具体的WindowManager操作。

WindowManagerGlobal内部维护了此WindowManager管理的所有View、ViewRoot和它们的LayoutParams,如下所示:

1
2
3
4
5
6
private final ArrayList<View> mViews = new ArrayList<View>();

private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();

private final ArrayList<WindowManager.LayoutParams> mParams =
new ArrayList<WindowManager.LayoutParams>();

简单的介绍了WindowManagerGlobal之后,继续来看addView的源码:

frameworks/base/core/java/android/view/WindowManagerGlobal.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
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {

···

ViewRootImpl root;
View panelParentView = null;

···

// 对于一个PanelWindow,需要找到它的父Window对应的View
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews.size();
for (int i = 0; i < count; i++) {
if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
panelParentView = mViews.get(i);
}
}
}

// 对于每一个Window 都有一个ViewRoomtImpl与之对应
root = new ViewRootImpl(view.getContext(), display);

view.setLayoutParams(wparams);

mViews.add(view);
mRoots.add(root);
mParams.add(wparams);

try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// 有可能会抛出熟知的BadTokenException异常
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}

此方法中创建了一个ViewRoomImpl,并且调用了ViewRoomImpl中的setView方法将当前view设置进去。

ViewRootImpl#setView

ViewRootImpl的setView方法代码比较多,我们只需要关注关键信息即可:

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
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;

···

int res; /* = WindowManagerImpl.ADD_OKAY; */

requestLayout();

mForceDecorViewVisibility = (mWindowAttributes.privateFlags
& PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
try {
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();

// 将Window与WindowManagerService绑定
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), mTmpFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel,
mTempInsets);
setFrame(mTmpFrame);
} catch (RemoteException e) {
mAdded = false;
mView = null;
mAttachInfo.mRootView = null;
mInputChannel = null;
mFallbackEventHandler.setView(null);
unscheduleTraversals();
setAccessibilityFocus(null, null);
throw new RuntimeException("Adding window failed", e);
} finally {
if (restore) {
attrs.restore();
}
}

···

}
}

可以看到方法中调用了requestLayout方法,而我们知道requestLayout方法最终会调用scheduleTraversals方法来发起整个View树的测量、布局与绘制工作。

View的绘制流程不是本文的重点,但这里我们获得了一个关键信息,就是Activity的Window显示过程,包括View树的绘制过程都是在Activity的ON_RESUME阶段来完成。

另外,调用了WindowSession中的addToDisplay方法,将Window与WindowManagerService绑定。

这就是为什么我们在onCreate、onStart和onResume中都无法同步到获取View的宽高。

Pause阶段

继续来看Pause阶段,根据经验我们直接来到ActivityThread中的handlePauseActivity方法。

ActivityThread#handlePauseActivity

handlePauseActivity方法表示自此Pause事件是由于用户导致,例如按下back键、home键、点击跳转Activity等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}

r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(r, finished, reason, pendingActions);

// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
mSomeActivitiesChanged = true;
}
}

performUserLeavingActivity中将会调用Activity中的onUserInteractiononUserLeaveHint方法。

ActivityThread#performPauseActivity

performPauseActivity方法中是会调用Activity的生命周期回调onPause方法,除了onPause方法,还有一些关键的方法也会在这里调用,例如onSaveInstanceState方法,来看看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {

···

// targetSDK < 11的App在pause前就会调用onSaveInstanceState
final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
if (shouldSaveState) {
// 调用onSaveInstanceState
callActivityOnSaveInstanceState(r);
}

// 回调生命周期方法 onPause
performPauseActivityIfNeeded(r, reason);

···

return shouldSaveState ? r.state : null;
}

ActivityThread#performPauseActivityIfNeeded

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {

···

try {
r.activity.mCalled = false;

// 回调onPause
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);
}
}

// 设置Lifecycle
r.setState(ON_PAUSE);
}

Activity#performPause

此方法与之前生命周期的工作类似,主要就是分发prePause、onPause和postPause事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
final void performPause() {
// 分发prePause
dispatchActivityPrePaused();
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;

// 回调生命周期方法
onPause();

mResumed = false;

···

// 分发postPause
dispatchActivityPostPaused();
}

Activity#onPause

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@CallSuper
protected void onPause() {
// 分发pause
dispatchActivityPaused();

// 是否需要自动填充
if (mAutoFillResetNeeded) {
if (!mAutoFillIgnoreFirstResumePause) {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "autofill notifyViewExited " + this);
View focus = getCurrentFocus();
if (focus != null && focus.canNotifyAutofillEnterExitEvent()) {
getAutofillManager().notifyViewExited(focus);
}
} else {
// reset after first pause()
if (DEBUG_LIFECYCLE) Slog.v(TAG, "autofill got first pause " + this);
mAutoFillIgnoreFirstResumePause = false;
}
}

notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_PAUSE);
mCalled = true;
}

Stop阶段

同样的,Stop阶段与前面的生命周期方法调用链是类似的。

ActivityThread#handleStopActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public void handleStopActivity(IBinder token, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
final ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;

final StopInfo stopInfo = new StopInfo();
performStopActivityInner(r, stopInfo, true /* saveState */, finalStateRequest,
reason);

// 更新Activity的显隐状态
updateVisibility(r, false);

···
}

handleStopActivity方法调用了performStopActivityInner来处理Activity的Stop状态,并且在Stop之后隐藏了Activity的DecorView的显示。

ActivityThread#performStopActivityInner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void performStopActivityInner(ActivityClientRecord r, StopInfo info, boolean keepShown,
boolean saveState, boolean finalStateRequest, String reason) {

···

// 保证Activity是处于Pause状态
performPauseActivityIfNeeded(r, reason);

···

if (!keepShown) {
// 回调Activiy的onStop方法
callActivityOnStop(r, saveState, reason);
}
}
}

performPauseActivityIfNeeded中上一节已经有调用过,是为了确保Activity调用了onPause,如果已经处于pause状态将会直接返回。

来看一下callActivityOnStop方法。

ActivityThread#callActivityOnStop

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
private void callActivityOnStop(ActivityClientRecord r, boolean saveState, String reason) {
// 在Android Honeycomb(11)之前,onSaveInstanceState都是在onPause之前执行
// 在Android P(28)之前,onSaveInstanceState在onStop方法执行之前执行
// 在Android P之后(包含),onSaveInstanceState在onStop方法执行之后执行
final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null
&& !r.isPreHoneycomb();
final boolean isPreP = r.isPreP();
if (shouldSaveState && isPreP) {
// 调用onSaveInstanceState
callActivityOnSaveInstanceState(r);
}

try {
// 调用onStop
r.activity.performStop(r.mPreserveWindow, 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);
}
}
r.setState(ON_STOP);

if (shouldSaveState && !isPreP) {
// 调用onSaveInstanceState
callActivityOnSaveInstanceState(r);
}
}

这里有个关键信息,就是onSaveInstanceState方法的调用时机。

之前在分析Pause阶段时,我们知道在Android Honeycomb以前onSaveInstanceState会在onPause方法调用之前回调,而在callActivityOnStop中进一步对onSaveInstanceState的调用时机做出了解释,总结如下:

  1. 在Android Honeycomb之前,onSaveInstanceState在onPause调用之前被调用
  2. 在Android Honeycomb之后,Android P之前,onSaveInstanceState在onStop调用之前被调用
  3. 在Android P之后,onSaveInstanceState在onStop调用之后被调用

performStop方法中会回调生命周期onStop方法,来看看。

Activity#performStop

此方法中同样会进行preStop、stop和postStop的事件分发,并且使用Instrumentation来回调onStop方法。

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
final void performStop(boolean preserveWindow, String reason) {

···

if (!mStopped) {

···

dispatchActivityPreStopped();
if (mWindow != null) {
mWindow.closeAllPanels();
}

···

mFragments.dispatchStop();

mCalled = false;
mInstrumentation.callActivityOnStop(this);

···

mStopped = true;
dispatchActivityPostStopped();
}
mResumed = false;
}

Activity#onStop

onStop方法中需要停止UI的刷新,停止运行中的动画,以及隐藏自动填充。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@CallSuper
protected void onStop() {
if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
mActivityTransitionState.onStop();
dispatchActivityStopped();
mTranslucentCallback = null;
mCalled = true;

if (mAutoFillResetNeeded) {
getAutofillManager().onInvisibleForAutofill();
}

if (isFinishing()) {
if (mAutoFillResetNeeded) {
getAutofillManager().onActivityFinishing();
} else if (mIntent != null
&& mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL,
mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
}
}
mEnterAnimationComplete = false;
}

Destroy阶段

Destroy阶段App除了要完成Activity本身的销毁逻辑外,还需要通知System Server来处理Activity栈相关的逻辑。

按照经验,我们来到ActivityThread的handleDestroyActivity方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
boolean getNonConfigInstance, String reason) {

// 销毁Activity
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance, reason);
if (r != null) {
// 处理Window相关
}
if (finishing) {
try {
// 通知ATMS此Activity已经被销毁
ActivityTaskManager.getService().activityDestroyed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}

此方法首先调用了performDestroyActivity执行了本地的销毁逻辑,然后通知ATMS更新系统服务。

ActivityThread#performDestroyActivity

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
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
ActivityClientRecord r = mActivities.get(token);
Class<? extends Activity> activityClass = null;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
if (r != null) {
activityClass = r.activity.getClass();
r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
}

// 保证Activity调用了onPause
performPauseActivityIfNeeded(r, "destroy");

if (!r.stopped) {
// 保证Activity调用了onStop
callActivityOnStop(r, false /* saveState */, "destroy");
}

···

try {
r.activity.mCalled = false;
// 调用onDestroy生命周期方法
mInstrumentation.callActivityOnDestroy(r.activity);

// 关闭所有window
if (r.window != null) {
r.window.closeAllPanels();
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
···
}
}
r.setState(ON_DESTROY);
}
schedulePurgeIdler();

// 删除本地Activity对应数据结构
synchronized (mResourcesManager) {
mActivities.remove(token);
}
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
}

Instrumentation.callActivityOnDestroy回调用Activity的performDestroy方法,与之前的生命周期类似,performDestroy方法主要是分发preDestroy、destroy和postDestroy事件,并且会调用onDestroy生命周期回调。

主要来看看onDestroy方法做了什么。

Activity#onDestroy

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
protected void onDestroy() {
mCalled = true;

// 关闭所有的dialog
// 使用Activity.showDialog显示的Dialog都会存入到mManagedDialogs中
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}

// 关闭所有的游标
// 使用startManagingCursor可以让Activity自动管理此游标避免泄漏
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}

// 关闭所有的SearchDialog
if (mSearchManager != null) {
mSearchManager.stopSearch();
}

if (mActionBar != null) {
mActionBar.onDestroy();
}

// 分发Destroy事件
dispatchActivityDestroyed();

notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_STOP);
}

onDestroy方法中主要是保证Activity销毁时已经关闭了所有的由此Activity管理的Dialog、Cursor和SearchDialog,可以避免一些内存泄漏。

非生命周期关键方法分析

上面分析完了Activity的生命周期的相关源码, 我们平时开发中除了与Activity生命周期回调方法打交道之外,通常还会涉及到少数非生命周期方法,例如onSaveInstanceState/onRestoreInstanceStateonRetainNonConfigurationInstance等,下面就来分析一下这几个函数的原理。

onSaveInstanceState

saveInstanceState中文翻译叫保存实例状态,它允许我们在Activity暂停或不可见时保存一些数据,然后通过onRestoreInstanceState来恢复这些数据,并且即使App被杀死,我们依然可以在onCreate方法中获取到保存的数据,这是如何做到的呢?

在上文的Stop阶段已经提到了onSaveInstanceState方法在callActivityOnSaveInstanceState中调用,并且对于不同的API版本调用时机是有区别的:

  1. 在Android Honeycomb(11)之前,callActivityOnSaveInstanceState在onPause调用之前被调用
  2. 在Android Honeycomb(11)之后,Android P之前,callActivityOnSaveInstanceState在onStop调用之前被调用
  3. 在Android P之后,callActivityOnSaveInstanceState在onStop调用之后被调用

下面来跟踪一下在Android Q中callActivityOnSaveInstanceState的调用流程。

ActivityThread#callActivityOnSaveInstanceState

callActivityOnSaveInstanceState方法定义在ActivityThread里面:

1
2
3
4
5
6
7
8
9
10
11
12
private void callActivityOnSaveInstanceState(ActivityClientRecord r) {
r.state = new Bundle();
r.state.setAllowFds(false);
// 是否设置了persistableMode为ActivityInfo.PERSIST_ACROSS_REBOOTS
if (r.isPersistable()) {
r.persistentState = new PersistableBundle();
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
}

可以看到这里新建了一个Bundle对象,并且赋值给了ActivityClientRecord的state属性,接着调用了Instrumentation中的callActivityOnSaveInstanceState方法。

Instrumentation.callActivityOnSaveInstanceState将会直接调用activity的performSaveInstanceState方法,我们直接来到Activity中。

Activity#performSaveInstanceState

1
2
3
4
5
6
7
8
9
10
final void performSaveInstanceState(@NonNull Bundle outState) {
dispatchActivityPreSaveInstanceState(outState);
onSaveInstanceState(outState);
// 调用此Activity管理的Dialog的onSaveInstanceState方法
saveManagedDialogs(outState);
mActivityTransitionState.saveState(outState);
storeHasCurrentPermissionRequest(outState);
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
dispatchActivityPostSaveInstanceState(outState);
}

可以看到onSaveInstanceState是在这里被调用的,重点也是这个方法。除此之外这里调用了saveManagedDialogs来调用此Activity管理的所有Dialog的onSaveInstanceState来保存数据。

继续来看onSaveInstanceState方法。

Activity#onSaveInstanceState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected void onSaveInstanceState(@NonNull Bundle outState) {
// 存储视图状态
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());

outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
// 存储Fragment信息
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mAutoFillResetNeeded) {
outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
getAutofillManager().onSaveInstanceState(outState);
}
dispatchActivitySaveInstanceState(outState);
}

此方法中调用了Window中的saveHierarchyState来保存所有视图的状态,另外调用了FragmentController的saveAllState方法来保存所有活动的Fragment信息。

分析一下这两个方法。

PhoneWindow#saveHierarchyState

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
public Bundle saveHierarchyState() {
Bundle outState = new Bundle();

// 如果没有调用setContentView,无需保存状态
if (mContentParent == null) {
return outState;
}

SparseArray<Parcelable> states = new SparseArray<Parcelable>();
// 调用ContentView的saveHierarchyState方法
// 会将onSaveInstanceState的调用分发给所有View
mContentParent.saveHierarchyState(states);
outState.putSparseParcelableArray(VIEWS_TAG, states);

// 保存当前FocusView的ID
final View focusedView = mContentParent.findFocus();
if (focusedView != null && focusedView.getId() != View.NO_ID) {
outState.putInt(FOCUSED_ID_TAG, focusedView.getId());
}

// 保存所有Panel的状态
SparseArray<Parcelable> panelStates = new SparseArray<Parcelable>();
savePanelState(panelStates);
if (panelStates.size() > 0) {
outState.putSparseParcelableArray(PANELS_TAG, panelStates);
}

// 保存ActionBar的状态
if (mDecorContentParent != null) {
SparseArray<Parcelable> actionBarStates = new SparseArray<Parcelable>();
mDecorContentParent.saveToolbarHierarchyState(actionBarStates);
outState.putSparseParcelableArray(ACTION_BAR_TAG, actionBarStates);
}

return outState;
}

此方法中会保存所有此Activity中的视图信息,包括actionBar。另外View的onSaveInstanceState也会在这里被递归的调用。

FragmentController#saveAllState

此方法将saveState事件传递给FragmentManager。

1
2
3
4
@Nullable
public Parcelable saveAllState() {
return mHost.mFragmentManager.saveAllState();
}

FragmentManager#saveAllState

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
Parcelable saveAllState() {

···

// 收集所有当前处于活动状态的Fragment的FragmentState
// 会调用Fragment的onSaveInstanceState方法
// 同时也会保存绑定的View的视图信息
ArrayList<FragmentState> active = mFragmentStore.saveActiveFragments();

if (active.isEmpty()) {
if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "saveAllState: no fragments!");
return null;
}

// 收集所有添加过的Fragment的FragmentState
// 会调用Fragment的onSaveInstanceState方法
// 同时也会保存绑定的View的视图信息
ArrayList<String> added = mFragmentStore.saveAddedFragments();

// 收集回退栈信息
BackStackState[] backStack = null;
if (mBackStack != null) {
int size = mBackStack.size();
if (size > 0) {
backStack = new BackStackState[size];
for (int i = 0; i < size; i++) {
backStack[i] = new BackStackState(mBackStack.get(i));
if (isLoggingEnabled(Log.VERBOSE)) {
Log.v(TAG, "saveAllState: adding back stack #" + i
+ ": " + mBackStack.get(i));
}
}
}
}

// 将收集到的信息封装成FragmentManagerState对象,它是个Parcelable
FragmentManagerState fms = new FragmentManagerState();
fms.mActive = active;
fms.mAdded = added;
fms.mBackStack = backStack;
fms.mBackStackIndex = mBackStackIndex.get();
if (mPrimaryNav != null) {
fms.mPrimaryNavActiveWho = mPrimaryNav.mWho;
}
fms.mResultKeys.addAll(mResults.keySet());
fms.mResults.addAll(mResults.values());
fms.mLaunchedFragments = new ArrayList<>(mLaunchedFragments);
return fms;
}

可以看到此方法主要做三件事:

  1. 收集所有当前处于活动状态的FragmentState
  2. 收集所有添加过的FragmentState
  3. 收集当前回退栈信息
  4. 将所有信息封装成FragmentManagerState对象并返回

到这里整个callActivityOnSaveInstanceState过程是如何收集需要保存的数据的已经分析完毕了。

前面说了,保存的数据会放到ActivityClientRecord的state对象里,根据前面的文章我们知道ActivityClientRecord仅仅是本地App中表示Activity的数据结构,而SaveInstanceState可以做到App被杀死后也能恢复数据,这说明数据并不单单是存储在本地App进程中,否则无法做到这一点。

不过在整个callActivityOnSaveInstanceState的调用过程中我们无法找到有持久化或者IPC调用任何操作,因此需要在callActivityOnSaveInstanceState调用后的代码中寻找。

最终在ActivityThread#performStopActivityInner找到关联的代码。

ActivityThread#performStopActivityInner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void handleStopActivity(IBinder token, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {

···

final StopInfo stopInfo = new StopInfo();
performStopActivityInner(r, stopInfo, true /* saveState */, finalStateRequest,
reason);

···

stopInfo.setActivity(r);
// 将保存的数据设置到了StopInfo中
stopInfo.setState(r.state);
stopInfo.setPersistentState(r.persistentState);
pendingActions.setStopInfo(stopInfo);
mSomeActivitiesChanged = true;
}

这里StopInfo它是一个Runnable,而我们收集到的数据state将会传递给它,然后将它设置给了PendingTransactionActions。既然是一个Runnable,那么它一定会在某个时间被调用,我们只需要关注其run方法即可。

StopInfo#run

1
2
3
4
5
6
7
8
public void run() {
// 通知ATMS此Activity已经Stopped
···
ActivityTaskManager.getService().activityStopped(
mActivity.token, mState, mPersistentState, mDescription);
···
}
}

此方法中通过调用ATMSactivityStopped方法来通知ATMS此Activity已经Stopped,并将mState属性传递给了方法。

由于篇幅限制,这里不再深入到ATMS中,实际上最终mState将会赋值给ActivityRecordicicle属性中,它也是一个Bundle对象。

到这里我们已经可以得出结论:onSaveInstanceState方法保存的数据将会通过IPC传递到SystemServer的ATMS中

总结

通过上述分析,我们知道了一下几点:

  • onSaveInstanceState方法将会在每次Activity onStop之前或者之后回调(不考虑Android 3.0以下的情况),在Android 9之前是onStop之前,Android 9之后是onStop之后。也就是说,只要Activity不可见了,就会回调onSaveInstanceState方法。
  • 在调用onSaveInstanceState时,会保存由当前绑定的Window来完成整个View树的状态保存,由FragmentManager来完成对Activity绑定的所有Fragment的状态保存。
  • 所有状态信息将会被存放到Bundle对象中,并且最终通过IPC传递给ATMS管理的ActivityRecord对象的icicle属性,因此是属于远端存储,这也是onSaveInstance只支持序列化数据的原因。

onRestoreInstanceState

缓存的数据会在Create阶段传入,另外Activity Start时候也会调用onRestoreInstanceState方法来恢复数据。

retainNonConfigurationInstances

如果读者用过ViewModel,会发现在Activity发生了Configuration改变导致的重建时,我们在Activity中(以此Activity为ViewModelStoreOwner)创建的ViewModel对象并不会发生改变。

如果查找过它的源码的话,实际上它是利用的Activity的retainNonConfigurationInstances方法来保存了一些非配置实例,其中包括由此Activity构建的ViewModel的存储类ViewModelStore

该方法声明在Activity.java类中,来看一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
NonConfigurationInstances retainNonConfigurationInstances() {
Object activity = onRetainNonConfigurationInstance();
HashMap<String, Object> children = onRetainNonConfigurationChildInstances();
FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig();

····

NonConfigurationInstances nci = new NonConfigurationInstances();
nci.activity = activity;
nci.children = children;
nci.fragments = fragments;
nci.loaders = loaders;
if (mVoiceInteractor != null) {
mVoiceInteractor.retainInstance();
nci.voiceInteractor = mVoiceInteractor;
}
return nci;
}

可以看到此方法中调用了三个关键方法来获取所有需要保存的非配置实例,并且封装成NonConfigurationInstances对象,三个方法分辨是:

  1. onRetainNonConfigurationInstance:获取此Activity需要保存的非配置实例
  2. onRetainNonConfigurationChildInstances:获取子Activity需要保存的非配置实例
  3. FragmentController#retainNestedNonConfig:获取此Activity管理的所有Fragment需要保存的非配置实例

其中Fragment的非配置实例保存已经被废弃了,由于ComponentActivity在配置变更时会保存ViewModel实例,所以Fragment也采用了ViewModel来保存它的非配置实例,由于篇幅有限这里不再深入。

我们重点来看onRetainNonConfigurationInstance方法,在Activity中是空实现,来看ComponentActivity的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public final Object onRetainNonConfigurationInstance() {
// 此方法被final修饰了,所以额外提供一个onRetainCustomNonConfigurationInstance方法给开发者使用
Object custom = onRetainCustomNonConfigurationInstance();

ViewModelStore viewModelStore = mViewModelStore;

// getViewModelStore未被调用
if (viewModelStore == null) {
// 此时要考虑我们的ViewModel是不是是在上个NonConfigurationInstances对象中取出来的
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
viewModelStore = nc.viewModelStore;
}
}

if (viewModelStore == null && custom == null) {
return null;
}

NonConfigurationInstances nci = new NonConfigurationInstances();
nci.custom = custom;
nci.viewModelStore = viewModelStore;
return nci;

此方法将创建的ViewModelStore对象保存到了NonConfigurationInstances实例中,可以看到ComponentActivity并不是直接保存所有的ViewModel,而是保存ViewModelStore,这样一次性就保存了所有从此ViewModelStoreOwner创建出来的ViewModel对象。

系统不希望我们继承这个方法,所以这里使用了final来修饰此方法,额外提供了一个onRetainCustomNonConfigurationInstance来允许开发者保存自己的非配置实例数据。

不过在有了ViewModel之后就不再需要利用此方法了,数据完全可以丢到ViewModel里。

到这里我们已经清楚了ViewModel对象是如何保存的,但是retainNonConfigurationInstances时机我们还不清楚。全局搜索一下,发现retainNonConfigurationInstances只有一次调用点,就是在ActivityThread的performDestroyActivity方法中:

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
ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {

ActivityClientRecord r = mActivities.get(token);

···

// 在relaunch时,getNonConfigInstance为true
if (getNonConfigInstance) {
try {

r.lastNonConfigurationInstances
= r.activity.retainNonConfigurationInstances();
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
"Unable to retain activity "
+ r.intent.getComponent().toShortString()
+ ": " + e.toString(), e);
}
}
}

···

return r;
}

performDestroyActivity我们已经有印象了,是在Activity的Destroy阶段会被调用,不过正常的Destroy流程中传入的getNonConfigInstance标志位为false,只有Activity Relaunch时才会为true。

方法中调用了Activity的retainNonConfigurationInstances方法并将结果赋值给了ActivityClientRecordlastNonConfigurationInstances属性,与onSaveInstanceState不同的是,retainNonConfigurationInstances存储的数据允许为Object类型,因为它并不需要IPC,仅仅只存储到本地App进程。

因此我们可以得出结论:当App退出或者被系统杀死时,ViewModel是无法还原数据的,其只适用于Activity由于Configuration的改变导致的重建情况。

最后来看一下这个lastNonConfigurationInstances如何重新交换给Activity,

在Activity的attach方法中有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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,
r.assistToken);

final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {

···

// 将lastNonConfigurationInstances重新赋值给Activity
mLastNonConfigurationInstances = lastNonConfigurationInstances;

···
}