這篇Activity的啟動模式也是一個難點,原因是啟動模式和標志實在是太容易被混淆了。有時我們為了滿足項目需求,需要用到對應的啟動模式。
我們在默認情況下,當我們多次啟動同一個Activity的時候,系統會創建實例化放入到任務棧中,當我們點擊back鍵,會發現這些Activity回退,任務棧遵循的是"后進先出"的原則??梢赃@樣理解,按一下back,就會有一個Activity出棧,直到棧頂為空,當棧中無任何Activity的時候,系統就會回收這個任務棧。Activity的四種啟動模式 分別為standard ?singleTop singleTask singleInstance。
standard 標準模式,這也是系統的默認模式,每次啟動一個Activity都會重新創建一個新的實例,不管這個實例是否存在,都會被創建。這是一個典型的多實例化,一個任務棧中可以有多個實例化,每個實例化也可以屬于不同的任務棧。這種啟動模式的特點就是 誰啟動了這個Activity 那么這個被啟動的Activity就在啟動Activity的棧中。例如 ActivityA啟動ActivityB 那么B就會進入A這個棧中。有個特殊的情況,就是在標準模式下用上下文去啟動Activity,切記不能使用ApplicationContext,否則就會報錯。因為ApplicationContext是沒有任務棧的。怎么解決這樣的問題呢?我們可以利用指定標記這種(FLAG_ACTIVITY_NEW_TASK),這樣就會創建一個新的任務棧。
singleTop 棧頂模式,很簡單的理解 當Activity在棧頂時,這個Activity就不會再次被創建。反之 如果不是在棧頂,這個Activity就會被重新創建。如果Activity是處于棧頂位置,我們需要注意的是 這是他們的生命周期 不會再經過onCreate,onStart因為并沒有重新創建。舉個例子簡單的例子,一個棧中有ABCD這四個Activity ?A處于棧頂,D處于棧底。這個時候我們啟動A,A的啟動模式為singleTop,那么棧中的情況還是ABCD,因為A是棧頂模式,所以在棧中沒有被重新創建,如果我們啟動D ,那么棧中的情況則為ABCDD,D位于棧底,需要被重新創建,棧中情況為ABCDD 。總之就是一句話,棧頂模式,誰在棧頂,就不會創建,反之,創建。當然,一個任務棧也只能并且有一個棧頂任務。
singleTask棧內復用模式,只要Activity在棧中存在,那么多次啟動的Activity都不會被重新創建,系統只需調用onNewIntent。簡單來講 就是A啟動了 是否有A所需要的棧,沒有則創建任務棧。然后再看看棧是否有A,有切換到棧頂,沒有則創建,壓入棧中。下面三種情況的例子,就能把singleTask理解的八八九九了。 因為這個singleTask 解釋的多了越讓人難以理解,所以就用這種簡潔明了的方式展現。
(1) 當任務棧R1有ABC三個Activity,那么D這時候以singleTask模式啟動,其所需要的是任務棧R2,由于R2和D都沒有實例,先創建任務棧R2,然后再創建D 放入其棧中R2中。
(2)?當任務棧R1有ABC三個Activity,那么D這時候以singleTask模式啟動,其所需要的是任務棧R1,那么D可以直接放入到R1棧中。
(3) 第三種情況 我們得知道singleTask具有clearTop的效果。任務棧R1已經存在,任務棧R1還有ABCD,此刻B進入任務棧R1,此時的B 是不會被創建,將B這個切換到棧頂,并調用onNewIntent方法,剛剛說了,具有clearTop效果,那么B之前的Activity全部出棧,于是最后的結果是AB。
singleInstance單實例棧模式,其實就是加強的singleTask模式,無非不一樣的是這種模式下的Activity單獨位于一個棧中。singleIntance的Activitya 系統創建一個新的任務棧,讓a獨立在這個棧中,由于棧內復用的關系,后面的就不會再進行創建,調用onNewintent,除非這個任務棧被銷毀。