在系列第二篇文章 中我们知道了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); mFragments.attachHost(null ); 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; ··· 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之后,完成一些收尾工作
此方法用于将同步启动的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的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) { dispatchActivityPreCreated(icicle); mCanEnterPictureInPicture = true ; restoreHasCurrentPermissionRequest(icicle); if (persistentState != null ) { onCreate(icicle, persistentState); } else { onCreate(icicle); } mActivityTransitionState.readState(icicle); mVisibleFromClient = !mWindow.getWindowStyle().getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false ); mFragments.dispatchActivityCreated(); mActivityTransitionState.setEnterActivityOptions(this , getActivityOptions()); 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) { 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); } 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 ); break ; case ON_START: mTransactionHandler.handleStartActivity(r, mPendingActions); break ; case ON_RESUME: mTransactionHandler.handleResumeActivity(r.token, false , r.isForward, "LIFECYCLER_RESUME_ACTIVITY" ); break ; case ON_PAUSE: mTransactionHandler.handlePauseActivity(r.token, false , false , 0 , mPendingActions, "LIFECYCLER_PAUSE_ACTIVITY" ); break ; case ON_STOP: mTransactionHandler.handleStopActivity(r.token, false , 0 , mPendingActions, false , "LIFECYCLER_STOP_ACTIVITY" ); break ; case ON_DESTROY: mTransactionHandler.handleDestroyActivity(r.token, false , 0 , false , "performLifecycleSequence. cycling to:" + path.get(size - 1 )); break ; case ON_RESTART: mTransactionHandler.performRestartActivity(r.token, false ); 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.performStart("handleStartActivity" ); r.setState(ON_START); if (pendingActions == null ) { return ; } 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); } } 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方法,此方法我们通常不会去重写它,主要是通知系统相关类来完成初始化。
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(); 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 ; boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning" , 0 ) == 1 ; 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 ; mFragments.doLoaderStart(); 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) { unscheduleGcIdler(); mSomeActivitiesChanged = true ; final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); if (r == null ) { return ; } if (mActivitiesToBeDestroyed.containsKey(token)) { return ; } final Activity a = r.activity; final int forwardBit = isForward ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0 ; boolean willBeVisible = !a.mStartedActivity; if (!willBeVisible) { try { willBeVisible = ActivityTaskManager.getService().willActivityBeVisible( a.getActivityToken()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } 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 ; ViewRootImpl impl = decor.getViewRootImpl(); if (impl != null ) { impl.notifyChildRebuilt(); } } if (a.mVisibleFromClient) { if (!a.mWindowAdded) { a.mWindowAdded = true ; wm.addView(decor, l); } else { a.onWindowAttributesChanged(l); } } } else if (!willBeVisible) { if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set" ); r.hideForNow = true ; } cleanUpPendingRemoveWindows(r, false ); if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null ) { 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(); 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 ; ··· 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); } } } 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) { 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; requestLayout(); mForceDecorViewVisibility = (mWindowAttributes.privateFlags & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0 ; try { mOrigWindowType = mWindowAttributes.type; mAttachInfo.mRecomputeGlobalAttributes = true ; collectViewAttributes(); 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); if (r.isPreHoneycomb()) { QueuedWork.waitToFinish(); } mSomeActivitiesChanged = true ; } }
performUserLeavingActivity中将会调用Activity中的onUserInteraction 和onUserLeaveHint 方法。
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) { ··· final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb(); if (shouldSaveState) { callActivityOnSaveInstanceState(r); } performPauseActivityIfNeeded(r, reason); ··· return shouldSaveState ? r.state : null ; }
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 ; mInstrumentation.callActivityOnPause(r.activity); ··· } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException("Unable to pause activity " + safeToComponentShortString(r.intent) + ": " + e.toString(), e); } } r.setState(ON_PAUSE); }
此方法与之前生命周期的工作类似,主要就是分发prePause、onPause和postPause事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 final void performPause () { dispatchActivityPrePaused(); mDoReportFullyDrawn = false ; mFragments.dispatchPause(); mCalled = false ; onPause(); mResumed = false ; ··· 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 () { 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 { 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 , finalStateRequest, reason); updateVisibility(r, false ); ··· }
handleStopActivity
方法调用了performStopActivityInner
来处理Activity的Stop状态,并且在Stop之后隐藏了Activity的DecorView的显示。
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) { ··· performPauseActivityIfNeeded(r, reason); ··· if (!keepShown) { 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) { final boolean shouldSaveState = saveState && !r.activity.mFinished && r.state == null && !r.isPreHoneycomb(); final boolean isPreP = r.isPreP(); if (shouldSaveState && isPreP) { callActivityOnSaveInstanceState(r); } try { 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) { callActivityOnSaveInstanceState(r); } }
这里有个关键信息,就是onSaveInstanceState
方法的调用时机。
之前在分析Pause阶段时,我们知道在Android Honeycomb 以前onSaveInstanceState
会在onPause方法调用之前回调,而在callActivityOnStop
中进一步对onSaveInstanceState
的调用时机做出了解释,总结如下:
在Android Honeycomb之前,onSaveInstanceState在onPause调用之前被调用
在Android Honeycomb之后,Android P之前,onSaveInstanceState在onStop调用之前被调用
在Android P之后,onSaveInstanceState在onStop调用之后被调用
performStop方法中会回调生命周期onStop方法,来看看。
此方法中同样会进行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) { ActivityClientRecord r = performDestroyActivity(token, finishing, configChanges, getNonConfigInstance, reason); if (r != null ) { } if (finishing) { try { ActivityTaskManager.getService().activityDestroyed(token); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } mSomeActivitiesChanged = true ; }
此方法首先调用了performDestroyActivity
执行了本地的销毁逻辑,然后通知ATMS更新系统服务。
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 ; } performPauseActivityIfNeeded(r, "destroy" ); if (!r.stopped) { callActivityOnStop(r, false , "destroy" ); } ··· try { r.activity.mCalled = false ; mInstrumentation.callActivityOnDestroy(r.activity); if (r.window != null ) { r.window.closeAllPanels(); } } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { ··· } } r.setState(ON_DESTROY); } schedulePurgeIdler(); 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 ; 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 ; } 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(); } if (mSearchManager != null ) { mSearchManager.stopSearch(); } if (mActionBar != null ) { mActionBar.onDestroy(); } dispatchActivityDestroyed(); notifyContentCaptureManagerIfNeeded(CONTENT_CAPTURE_STOP); }
onDestroy方法中主要是保证Activity销毁时已经关闭了所有的由此Activity管理的Dialog、Cursor和SearchDialog,可以避免一些内存泄漏。
非生命周期关键方法分析 上面分析完了Activity的生命周期的相关源码, 我们平时开发中除了与Activity生命周期回调方法打交道之外,通常还会涉及到少数非生命周期方法,例如onSaveInstanceState/onRestoreInstanceState 、onRetainNonConfigurationInstance 等,下面就来分析一下这几个函数的原理。
onSaveInstanceState saveInstanceState中文翻译叫保存实例状态 ,它允许我们在Activity暂停或不可见时保存一些数据,然后通过onRestoreInstanceState来恢复这些数据,并且即使App被杀死,我们依然可以在onCreate方法中获取到保存的数据 ,这是如何做到的呢?
在上文的Stop阶段已经提到了onSaveInstanceState
方法在callActivityOnSaveInstanceState
中调用,并且对于不同的API版本调用时机是有区别的:
在Android Honeycomb(11)之前,callActivityOnSaveInstanceState在onPause 调用之前 被调用
在Android Honeycomb(11)之后,Android P之前,callActivityOnSaveInstanceState在onStop 调用之前 被调用
在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 ); 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中。
1 2 3 4 5 6 7 8 9 10 final void performSaveInstanceState (@NonNull Bundle outState) { dispatchActivityPreSaveInstanceState(outState); onSaveInstanceState(outState); 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); 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(); if (mContentParent == null ) { return outState; } SparseArray<Parcelable> states = new SparseArray<Parcelable>(); mContentParent.saveHierarchyState(states); outState.putSparseParcelableArray(VIEWS_TAG, states); final View focusedView = mContentParent.findFocus(); if (focusedView != null && focusedView.getId() != View.NO_ID) { outState.putInt(FOCUSED_ID_TAG, focusedView.getId()); } SparseArray<Parcelable> panelStates = new SparseArray<Parcelable>(); savePanelState(panelStates); if (panelStates.size() > 0 ) { outState.putSparseParcelableArray(PANELS_TAG, panelStates); } 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 () { ··· ArrayList<FragmentState> active = mFragmentStore.saveActiveFragments(); if (active.isEmpty()) { if (isLoggingEnabled(Log.VERBOSE)) Log.v(TAG, "saveAllState: no fragments!" ); return null ; } 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 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; }
可以看到此方法主要做三件事:
收集所有当前处于活动状态的FragmentState
收集所有添加过的FragmentState
收集当前回退栈信息
将所有信息封装成FragmentManagerState对象并返回
到这里整个callActivityOnSaveInstanceState
过程是如何收集需要保存的数据的已经分析完毕了。
前面说了,保存的数据会放到ActivityClientRecord 的state对象里,根据前面的文章我们知道ActivityClientRecord仅仅是本地App中表示Activity的数据结构,而SaveInstanceState可以做到App被杀死后也能恢复数据,这说明数据并不单单是存储在本地App进程中,否则无法做到这一点。
不过在整个callActivityOnSaveInstanceState
的调用过程中我们无法找到有持久化 或者IPC调用 任何操作,因此需要在callActivityOnSaveInstanceState
调用后的代码中寻找。
最终在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 , finalStateRequest, reason); ··· stopInfo.setActivity(r); 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 () { ··· ActivityTaskManager.getService().activityStopped( mActivity.token, mState, mPersistentState, mDescription); ··· } }
此方法中通过调用ATMS 的activityStopped
方法来通知ATMS此Activity已经Stopped,并将mState属性传递给了方法。
由于篇幅限制,这里不再深入到ATMS中,实际上最终mState将会赋值给ActivityRecord 的icicle 属性中,它也是一个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对象,三个方法分辨是:
onRetainNonConfigurationInstance :获取此Activity需要保存的非配置实例
onRetainNonConfigurationChildInstances :获取子Activity需要保存的非配置实例
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 () { Object custom = onRetainCustomNonConfigurationInstance(); ViewModelStore viewModelStore = mViewModelStore; if (viewModelStore == null ) { 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); ··· 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
方法并将结果赋值给了ActivityClientRecord 中lastNonConfigurationInstances 属性,与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) { ··· mLastNonConfigurationInstances = lastNonConfigurationInstances; ··· }