簡單的來講,一個 Activity 包含了用戶能夠看到的界面,用來和用戶進行交互。一個應用程序中能夠有零個或者多個 Activity。零個 Activity 的話就是,這個程序不包含與用戶交互的界面。android
Android 是使用任務(Task)來管理 Activity 的。一個 Task 就是一組存放在棧裏的 Activity 的集合。這個任務也被稱爲返回棧(Back Stack),棧是一種先進先出的數據結構,默認狀況下,每當咱們啓動了一個新的 Activity,它會被加入到棧中,並處於棧頂的位置,當 Activity 的 finish 方法去銷燬一個 Activity 的時候,這個 Activity 就會出棧。系統老是會顯示處於棧頂的 Activity 給用戶。數據結構
每一個 Activity 在其生命週期中最多可能會有 4 中狀態佈局
運行狀態spa
當一個 Activity 位於返回棧的棧頂的時候,這個時候這個 Activity 就處於運行狀態。這個時候是最不容易被系統回收的。.net
暫停狀態3d
當一個 Activity 再也不處於棧頂位置,可是仍然可見的時候,這種狀況下這個 Activity 就處於暫停狀態。Activity 不在棧頂了居然還能被看到?你想若是棧頂的 Activity 是一個對話框或者是透明的狀況下,是否是這個不在棧頂位置的 Activity 依然能夠被用戶看到啊。這種狀態的 Activity,系統也是不肯意去回收的。code
中止狀態cdn
當一個 Activity 再也不處於棧頂位置,並且徹底看不到的時候,就進入了中止狀態了。系統仍然會爲這樣的 Activity 保留響應的狀態和成員變量,但這並非徹底可靠的,當內存緊張的時候,處於中止狀態的 Activity 有可能被系統回收。xml
銷燬狀態blog
當一個 Activity 從返回棧移除後就變成銷燬狀態了,系統傾向回收處於這種狀態的 Activity。
先放上一張最經典的圖
onCreate()
會在 Activity 第一次被建立的時候調用,應該在這個方法中完成 Activity 的初始化操做,好比加載佈局、綁定事件等等。
onStart()
Activity 由不可見狀態變爲可見狀態。
onResume()
這個方法在 Activity 準備好和用戶進行交互的時候調用,此時 Activity 必定處於返回棧的棧頂,而且處於運行狀態。
onPause()
這個方法在系統準備去啓動或者恢復另外一個 Activity 的時候調用。一般會在這個方法中將一些消耗 CPU 的資源釋放,保存一些關鍵的數據,可是這個方法的執行速度必定要快,否則會影響新的棧頂 Activity 的使用。
onStop()
在 Activity 徹底不可見的時候調用。
onDestroy()
這個方法在被銷燬以前調用,以後 Activity 的狀態就變爲銷燬狀態。
onRestart()
這個方法在 Activity 由中止狀態變爲運行狀態以前調用,也就是 Activity 被從新啓動了。
以上 7 個方法中除了 onRestart 方法,其餘都是兩輛相對的,從而又能夠將 Activity 分爲 3 中生存期。
上面都是正常狀況的下面生命週期,下面來幾個比較有特色的生命週期。
onCreate ->onStart -> onResume -> onPause -> onStop -> B 的生命週期
。onCreate ->onStart -> onResume -> onPause -> B 的生命週期
。Activity 進入中止狀態後,就有可能被系統回收。Activity 爲咱們提供了一個方法 onSaveInstanceState()
回調方法,這個方法能夠保證在 Activity 被回收以前必定會被調用,咱們能夠經過這個方法來保存一些臨時數據。
啓動模式一共有 4 中:standard、singleTop、singTask 和 singleInstance,能夠在 AndroidManifest.xml
中經過 <activity>
標籤指定 android:launchMode
屬性來選擇啓動模式。
standard 模式是 Activity 的默認啓動模式,在不進行顯示指定的狀況下,全部 Activity 都會自動使用這種啓動模式。這種模式下,每當啓動一個新的 Activity,它就會在返回棧的棧頂位置。對於使用 standard 模式啓動的 Activity,系統不會在意這個 Activity 是否已經存在在棧中了。每次啓動的時候都會建立一個新的實例。
誰啓用了這個模式的 Activity,那麼這個 Activity 就屬於啓動它的 Activity 的任務棧。
若是 Activity 指定爲 singleTop,在啓動 Activity 的時候發現返回棧的棧頂已是該 Activity 了。則認爲能夠直接使用它,就不會再建立新的 Activity 實例了。
由於不會建立新的 Activity 實例,因此 Activity 的生命週期就沒有什麼變化了。可是它的 onNewIntent
方法會被調用。
singleTop 很好的解決了重複建立棧頂 Activity 的問題。若是 Activity 沒有處於棧頂的位置,仍是可能會建立多個 Activity 實例的。如何解決這種問題呢?那就須要藉助 singleTask 了。當 Activity 的啓動模式爲 singleTask 的時候,每次啓動該 Activity 的時候系統會首先在返回棧中檢查是否存在該 Activity 的實例,若是發現已經存在則直接使用該實例。並把這個 Activity 之上的全部 Activity 所有出棧,若是沒有就會建立一個新的 Activity 實例。
生命週期正常調用,onNewIntent 也會被調用。
singleInstance 模式的 Activity 會啓用一個新的返回棧來管理這個 Activity (其實若是 singleTask 模式指定了不一樣的 taskAffinity,也會啓動一個新的返回棧)。意義:假如咱們的程序中有一個 Activity 是容許其餘程序調用的,若是咱們想實現其餘程序和咱們的程序能夠共享這個 Activity 實例。那麼如何實現呢?假如使用前面 3 中啓動模式,確定不行。由於,咱們每一個應用程序都有本身的返回棧,雖然是一樣這個 Activity,可是在不一樣的返回棧入棧的時候確定是建立了新的實例了。而 singleInstance 能夠解決這個問題,在這種模式下會有一個單獨的返回棧來管理這個 Activity,不論是那個應用程序來訪問這個 Activity,都共用的同一個返回棧,也就解決了共享 Activity 實例的問題。
standard 和 singleTop 啓動模式都是在原任務棧中新建 Activity 實例,不會啓動新的 Task,即便你指定了 taskAffinity 屬性。
什麼是 taskAffinity 屬性
taskAffinity 屬性不對 standard 和 singleTop 模式有任何影響 即便咱們給這兩種模式設置了
<activity android:name=".ActivityStandard" android:launchMode="standard" android:taskAffinity="com.syd"/>
複製代碼
只是改變了 taskAffinity 的名字,可是任務棧依然仍是啓動這個 Activity 的 Activity 所在的任務棧。
singleTask 模式的 Activity 的啓動,啓動的時候會根據 taskAffinity 去尋找當前是否存在這麼一個任務棧,若是不存在就會建立一個新的任務棧,並建立新的 Activity 實例到進建立的任務棧中。若是存在,則查找任務棧中是否有該 Activity 的實例。
任務棧是能夠跨程序的。
參考:《第一行代碼》、blog.csdn.net/mynameishua…