天天看點

1.Activity正常狀況下的生命周期的擴充學習筆記

1.1  啟動Activity的時候的特殊情況        一般來說,使用者打開新的Activity或者切換到桌面的時候,回調如下:  onPause->onStop。       但是,如果Activity采用的是透明主題,那麼目前的Activity是不會回調onStop的。 1.2 被回收的Activity再次啟動     當Activity被系統回收了以後再次打開,生命周期方法回調過程還是和第一次打開的一樣,但是,這隻是說生命周期方法一樣,這不代表所有的過程都一樣。 1.3 Activity生命周期的對稱性     從整個生命周期來說,onCreate對應于onDestory,onResume對應onPause ,onStart對應onRestart.其中,前者隻能有一次調用,而後者可以多次調用。 1.4 onResume和onStart,onPause和onStop看似相似,卻有不同     onStart和onResume,onPause和onStop從描述上看是差不多的,但是,卻是有着一些實質性的不同。     這裡面實質性的不同,就是他們所處的生命周期的不同,onStart、onStop表示的是,Activity是否可見,而onResume、onPause則是從是否運作在前台的角度來處理的,從可靠性來說,onPause是比onStop更加可靠的。

1.5 不同Activity的onResume和onPause誰先誰後?     假設目前Activity為A,接下來要打開一個新的ActivityB,那麼B的onResume和A的onPause哪個先執行呢?     這個需要從Activity源碼那邊開始入手,Activity的啟動過程,涉及到了Instrumentation、ActivityThread和ActivityManagerService(AMS).     Activity的啟動請求會通過Instructmentation來處理,然後Instructmentation通過Biner向AMS送出請求,AMS内部維護着一個ActivityStack,并且負責棧内的Activity的狀态同步,AMS通過ActivityThread去同步Activity的狀态,完成生命周期方法的調用。     在ActivityStatck(com.android.server.am包中)中的resumeTopActivityInnerLocked方法中,有這樣一段代碼:             // We need to start pausing the current activity so the top one         // can be resumed...         boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving);         if (mResumedActivity != null) {             pausing = true;             startPausingLocked(userLeaving, false);             if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);         }      if (pausing) {             if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,                     "resumeTopActivityLocked: Skip resume: need to start pausing");             // At this point we want to put the upcoming activity's process             // at the top of the LRU list, since we know we will be needing it             // very soon and it would be a waste to let it get killed if it             // happens to be sitting towards the end.             if (next.app != null && next.app.thread != null) {                 // No reason to do full oom adj update here; we'll let that                 // happen whenever it needs to later.                 mService.updateLruProcessLocked(next.app, false, true);             }             if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();             return true;         }

    從上述代碼可以看出,在新Activity啟動之前,棧頂的Activity需要先onPause才會啟動新的Activity.最終,在ActivityStatckSupervisor中的realStartActivityLocked方法毀調用下面這個代碼:      a pp.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,                     System.identityHashCode(r), r.info,                     new Configuration(mService.mConfiguration), r.compat,                     app.repProcState, r.icicle, results, newIntents, !andResume,                     mService.isNextTransitionForward(), profileFile, profileFd,                     profileAutoStop);     上面代碼中的app類型為: ProcessRecord 。      檢視ProcessRecord 中thread的代碼:     IApplicationThread thread;  // the actual proc...  may be null only if                                 // 'persistent' is true (in which case we                                 // are in the process of launching the app) 可以知道,類型為IApplicationThread,上面說具體實作就是在App運作的程序中,那麼可以知道這個代碼的具體實作就是在ActivityThread,是以實際上調用的是ActivityThread的scheduleLauchActivity方法,而scheduleLauchActivity方法最終會完成新Activity的onCreate、onStart、onResume的調用過程,     具體代碼如下:            public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,                 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,                 int procState, Bundle state, List<ResultInfo> pendingResults,                 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,                 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;             r.ident = ident;             r.intent = intent;             r.activityInfo = info;             r.compatInfo = compatInfo;             r.state = state;

            r.pendingResults = pendingResults;             r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;             r.isForward = isForward;

            r.profileFile = profileName;             r.profileFd = profileFd;             r.autoStopProfiler = autoStopProfiler;

            updatePendingConfiguration(curConfig);

            queueOrSendMessage(H.LAUNCH_ACTIVITY, r);         }     其中:        queueOrSendMessage(H.LAUNCH_ACTIVITY, r);     上面這一行會通過一個類型為:H(命名我mH)的Handler對象接收到消息以後,在handlerLaunchActivity方法中來實作新Activity的onCreate、onStart、onResume。     是以結論得出:舊的Activity先onPause,新的Activity再啟動。

1.6 關于onPause的解釋:     Android官方文檔在onPause中标注了如下:            When activity B is launched in front of activity A, this callback will   be invoked on A.  B will not be created until A's {@link #onPause} returns,  so be sure to not do anything lengthy here.     意思就是不要在onPause中做耗時的操作,因為新的Activity會在onPause以後才開始顯示到前台。是以耗時操作應該放在onStop中,(onStop不會影響新的Activity的顯示)onPause适合做一些儲存應用目前的運作資料、如果沒有足夠多的資源去啟動新的Activity那麼更要持久化資料,并且在這裡最好暫停一些動畫啊等消耗CPU資源的操作,使得下一個Activity可以快速啟動起來。或者關閉一些唯一的單獨的資源通路接口,比如說關閉調用相機。 本文參考 任玉剛先生的《Anroid開發藝術探索》書和官方文檔。     

繼續閱讀