Android群英傳讀書筆記(第八章)
本章主要介紹的是Activity和Acitivity調用棧的分析。
## 1.Activity
* Activity形態(不是Activity生命周期):
* Active/Running:Activity處于棧的最頂層,可見,并且與用戶進行交互。
* Paused:當Activity失去焦點,被一個新的非全屏的Activity或者一個透明的Activity放置在棧頂時,Activity就轉化為Paused狀態。它只是失去了與用戶交互的能力,所有狀態信息、成員變量都還保持著,只有內存極為不足時才會被系統回收。
* Stopped:如果一個Activity被另一個Activity完全覆蓋,Activity進入Stopped狀態。此時它不可見,但是依然保存了所有信息狀態還成員變量。
* Killed:當Activity被系統回收掉或者Activity從來沒有創建過,Activity就處于Killed狀態。
* Activity生命周期:
生命周期

生命周期的東西比較基礎簡單,這里就貼一張圖,關于生命周期的資料百度也一堆就不過多記錄了。
這里記錄一個Activity重新創建的過程:如果Activity長時間處于stopped狀態,而此時系統內存也較為緊張時,系統就會回收Activity。此時會將Activity狀態通過onSaveInstanceState()來保存到Bundle對象中,也可以增加額外的鍵值對存入Bundle中。當需要重新創建Activity時,保存的Bundle對象就會傳遞到Activity的onRestoreInstanceState()與onCreate()方法中。需要注意的是,如果用戶使用finish()方法結束了Activity則不會調用。
## 2.Android任務棧
當啟動一個App時,如果當前環境中不存在該App的任務棧,那么系統會創建一個任務棧,用來管理這個App的的Activity。這個棧也叫作Task,即表若干個Activity的集合。另外,一個Task中的Activity可以來自不同App,同一個App的Activity不一定在一個Task中。
## 3.AndroidMainifest啟動模式
Android總共有四種啟動模式:
* standard:
默認的啟動模式,這種啟動模式每次都會創建新的實例覆蓋在原來的Activity上。
* singleTop:
在啟動時,系統會判斷當前棧頂Activity是不是要啟動的Activity,如果是則不創建新的Activity而直接引用它,如果不是則創建。這種啟動模式通常適用于接受到消息后顯示的界面,例如qq接收到消息后彈出Activity,如果一次來了10條消息,顯示的都是同一個Activity。
* singleTask:
和singleTop相似,不同之處是這種啟動模式會檢查任務棧中是否已經存在該Activity,如果存在則將該Activity置頂,并將該Activity以上的Activity都銷毀。如果是其他app來以singleTask的模式來創建這個Activity時,它將創建一個新的任務棧。如果該模式的Activity已經在后臺一個任務棧中了,那么啟動后,后臺的這個任務棧將一起被切換到前臺,如圖:

使用這種模式創建的Activity不是在新的任務棧中被打開,就是將已經打開的Activity切換到前臺,所以通常這種模式可以用來退出整個應用:將主Activity設為singleTask,然后要退出的Activity轉到主Activity,從而將主Activity上的Activity都清除,然后重寫主Activity的onNewIntent()方法,在方法中加上一句finish(),將最后一個Activity結束掉。
* singleInstance:
這種啟動模式和使用瀏覽器的工作原理類似,在其他程序訪問瀏覽器時,如果瀏覽器尚未打開則會開啟瀏覽器,否則就會在已經開打的瀏覽器上進行訪問。singleInstance的Activity會出現在一個新的任務棧中,并且該任務棧只有一個Activity存在。如果A應用創建了一個singleInstance的Activity,B應用想要啟動它的時候則不需要再次創建,兩個應用將共享該Activity。這種啟動模式常用于需要與程序分離的界面。
注意:如果啟動模式為singleTop或者singleInstance時,Activity調用startActivityForResult()方法來啟動另一個Activity,那么系統將直接返回Activity.RESULT_CANCELED,這是由于Framework層對這兩種模式進行了限制,不同Task默認是不能傳遞數據的,需要通過Intent才行。
## 4.Intent Flag啟動模式
文中介紹了一些常用的IntentFlag。
* Intent.FLAG_ACTIVITY_NEW_TASK:
使用一個新的Task來啟動Activity。通常應用于Service啟動Activity的場景,由于在Service中并不存在Activity棧,所以使用該Flag來創建一個新的Activity棧,并創建新的Activity實例。
* Intent.FLAG_ACTIVITY_SINGLE_TOP:
與指定android:launchMode="singleTop"同效果。
* Intent.FLAG_ACTIVITY_CLEAN_TOP:
與指定android:launchMode="singleTask"同效果。
* Intent.FLAG_NO_HISTORY:
使用這種模式啟動Activity,當該Activity啟動其他Activity后,該Activity就消失了,不會保留在Task中。
## 5.清空任務棧
系統提供了清空任務棧的方法來讓我們將一個Task全部清除。通常情況下,可以在AndroidMainifest文件中的<activity>標簽中使用以下幾種屬性來清理任務棧。
* clearTaskOnLaunch
clearTaskOnLaunch屬性顧名思義,就是在每次返回該Activity時,將該Activity之上的Activity都清除。
* finishOnTaskLaunch
當離開這個Activity所處的Task,那么返回時,該Activity將被finish。
* alwaysRetainTaskState
如果將Activity這個屬性設置為true,那么該Activity所處的Task將不接受任何清理指令,一直保持當前Task狀態。