Activity的生命週期和啓動模式

一、Activity的生命週期

1、典型情況下的生命週期

(1)onCreate

    表示activity正在被創建,生命週期的第一個方法,我們可以在這裏面去做一些初始化的工作。比如加載界面佈局等等。

(2)onRestart

    activity正在重新啓動,由不可見狀態變爲可見狀態。一般調用了onStop之後,再回到這個activity,就會調用onRestart.

(3)onStart

    表示activity正在被啓動,這個時候acitvity已經可見了,但是沒有出現在前臺,無法進行交互,可以理解爲activity已經顯示出來了但是用戶看不到。

(4)onResume

    表示activity已經可見了,並且出現在前臺。注意:onStart和onResume都表示activity已經可見,但是onStart的時候activity還在後臺,onResume才顯示到前臺。

(5)onPause

    表示activity正在被停止,正常情況下,緊接着onStop就會被調用。在特殊情況下,如果快速返回到當前的activity,那麼onResume就會被調用(極端情況).這個時候可以做一些存儲數據,停止動畫的工作,但是注意不能太耗時,因爲這會影響到新的activity的顯示,onPause必須先執行完,新activity的onResume纔會執行.

(6)onStop

    表示activity即將停止,這時可以做一些掃尾重量級的工作,但是同樣不能太耗時.

(7)onDestroy

    表示activity即將銷燬,activity生命週期的最後一個回調.在這裏我們可以做一些回收工作和最終的資源的釋放.

這裏寫圖片描述

(8)注意

    (1)activity第一次啓動,回調如下:onCreate->onStart->onResume.如果activity被系統回收了再次打開,回調也是這樣的.
    (2)當用戶打開了新的activity或者回到桌面時.回調如下:onPause->onStop.如果新activity採用了透明的主題則不會回調onStop.
    (3)當用戶回到原來的activity時,回調如下:onRestart->onStart->onResume.
    (4)當用戶按back鍵回退時:回調如下:onPause->onStop->onDestroy.
    (5)從整個生命週期來說,onCreate和onDestroy是配對的,標誌着activity的創建和銷燬.並且只會調用一次.從activity是否可見來說,onStart和onStop是配對的,這2個方法可能會被多次調用.從activity是否在前臺來說,onResume和onPause是配對的,也可能會被多次調用.

2、異常情況下的生命週期

    (1)切換橫豎屏時.不設置Activity的android:configChanges時,切屏會重新調用各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次.同時由於activity是在異常情況下終止的,系統會調用onSaveInstanceState來保存當前Activity的狀態,這個方法是在onStop之前執行的,但是和onPause沒有太大的時序關係.這個方法只會出現在activity被異常終止的情況下.activity被重新創建後,系統會調用onRestoreInstanceState,並把activity銷燬時調用onSaveInstanceState方法所保存的Bundle對象傳給onRestoreInstanceState和oncreate方法.我們可以根據這個來判斷activity是否被重建.onRestoreInstanceState出現在onStart之後.
    設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命週期,切橫、豎屏時只會執行一次.
    設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命週期,只會執行onConfigurationChanged方法.
    (2)資源內存不足導致低優先級的activity被系統殺死.這個時候它的數據的保存和恢復情況與上面的基本一致.

二、Activity的啓動模式

(1)、activity的launcherMode

    默認情況下,當我們多次啓動同一個activity時,系統是用棧(後進先出)來存儲這些activity實例的,當我們單擊back鍵時就會有一個activity出棧,知道最後一個activity出棧,系統就會回收這個棧.接下來我們介紹activity的4種啓動模式:standard(默認啓動模式),singleTop,singleTask,singleInstance.

(1)standard

    默認啓動模式,每次啓動activity都會重新創建一個實例,這是一種典型的多實例實現,一個棧中可以有多個實例,每個實例也可以屬於不同的棧,在這種模式下,誰啓動了這個activity,那麼這個activity就運行在啓動它的那個activity所在的棧中.

(2)singleTop

    棧頂複用模式,這種模式下,如果新的activity處於棧頂,那麼就不會被重新創建,同事它的onNewIntent方法會被回調,如果不是位於棧頂時,則和standard模式一樣.

(3)singleTask

    站內複用模式,這是一種單例模式,這種模式下,只要activity在一個棧中存在,那麼多次啓動這個activity都不會重新創建實例.而是和singleTop一樣,會調用他的onNewIntent方法.具體來說,當一個具有singleTask模式的activity請求啓動後,比如activity A,系統首先會尋找是否存在activity A想要的棧,如果不存在則重新創建一個棧,然後創建activity A的實例,並放入棧中.如果有activity A所需要的棧,則看棧中是否有activity A的實例,如果實例存在,那麼系統就會把activity A上面的其他實例出棧,將activity A放在棧頂並調用它的onNewIntent方法,如果棧內沒有activity A的實例,就創建一個activity A的實例,並壓入棧中.

(4)singleInstance

    單實例模式,一種加強版的singleTask模式,除了具有singleTask模式的所有特性外,還加強了一點,就是具有這種模式的activity只能單獨的位於一個棧中,意思就是,例如activity A是這種模式,那麼當activity A啓動時,系統會爲它創建一個新的任務棧,然後activity A的實例肚子在這個棧中.後面在啓動這個activity都不會創建新的activity A的實例,除非這個棧被系統銷燬了.

(5)注意

    (1)我們曾多次的提到了棧,那麼什麼是Activity所需要的棧呢?這首先重一個參數說起TaskAffinity(任務相關性),這個參數標識了一個activity所需要的棧的名字,默認情況下所有的activity的所屬的棧名都是它應用的包名,當然我們可以通過TaskAffinity來給activity來指定棧名,不能和包名相同,不然就沒有意義了.TaskAffinity屬性主要還是和singleTask啓動模式和allowTaskReparenting屬性配對使用,在其他情況下沒有意義.另外棧分爲前臺任務棧和後臺任務棧,後臺任務棧的activity位於暫停狀態.
    當TaskAffinity與singleTask啓動模式配對使用時acitvity會運行在名字和TaskAffinity形同的任務棧中.
    當TaskAffinity與allowTaskReparenting屬性結合的時候比較複雜,暫時不討論

    (2)如何給activity指定啓動模式呢?有2種方法,1、在manifest中指定

這裏寫圖片描述
1、通過在Intent中設置標誌位來指定
這裏寫圖片描述
第二種的優先級要高於第一種,如果同時存在的話,以第二種爲準.而且第一種無法爲activity設定FLAG_ACTIVITY_CLEAR_TOP標誌,第二種無法指定activity singleInstance模式.

(6)Activity的Flags

    FLAG_ACTIVITY_NEW_TASK,指定爲singleTask啓動模式.
    FLAG_ACTIVITY_SINGLE_TOP,指定爲singleTop啓動模式.
    FLAG_ACTIVITY_CLEAR_TOP,具有此標誌的activity,當它啓動時同一個棧中位於它上面的activity實例都要出棧,這個模式一般需要和FLAG_ACTIVITY_NEW_TASK配合使用,在這種情況下,被啓動的activity如果已經存在那麼就會調用他的onNewIntent方法,如果被啓動的activity採用的是默認的啓動模式那麼它連同它之上的activity都要出棧,系統會創建新的activity實例並放入棧頂.singleTask啓動模式默認就具有此標記的效果.
    FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,具有這個標誌的activity不會出現在歷史activity列表裏面,等同於在manifest中指定activity的屬性android:excludeFromRecents="true".
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章