天天看點

Activity之啟動模式

1、Activity的幾種LaunchMode及使用場景

standard 模式

這是預設模式,每次激活Activity時都會建立Activity執行個體,并放入任務棧中。使用場景:大多數Activity。

  • singleTop 模式

如果在任務的棧頂正好存在該Activity的執行個體,就重用該執行個體( 會調用執行個體的 onNewIntent() ),否則就會建立新的執行個體并放入棧頂,即使棧中已經存在該Activity的執行個體,隻要不在棧頂,都會建立新的執行個體。使用場景如新聞類或者閱讀類App的内容頁面。

  • singleTask 模式

如果在棧中已經有該Activity的執行個體,就重用該執行個體(會調用執行個體的 onNewIntent() )。重用時,會讓該執行個體回到棧頂,是以在它上面的執行個體将會被移出棧。如果棧中不存在該執行個體,将會建立新的執行個體放入棧中。使用場景如浏覽器的主界面。不管從多少個應用啟動浏覽器,隻會啟動主界面一次,其餘情況都會走onNewIntent,并且會清空主界面上面的其他頁面。

  • singleInstance 模式

在一個新棧中建立該Activity的執行個體,并讓多個應用共享該棧中的該Activity執行個體。一旦該模式的Activity執行個體已經存在于某個棧中,任何應用再激活該Activity時都會重用該棧中的執行個體( 會調用執行個體的 onNewIntent() )。其效果相當于多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。使用場景如鬧鈴提醒,将鬧鈴提醒與鬧鈴設定分離。singleInstance不要用于中間頁面,如果用于中間頁面,跳轉會有問題,比如:A -> B (singleInstance) -> C,完全退出後,在此啟動,首先打開的是B。

===============================================================================

LaunchMode

(注意:以下測試截圖和關系等,都是在未殺程序下進行)

  • standard 模式

1、在Activity啟動模式預設的情況下,建立3個Activity,Test1、Test2、Test3。

(1)進入棧:關系為Test1–>Test2–>Test3–>Test2

activity棧如下:

Activity之啟動模式

生命周期如下:

Activity之啟動模式

(2)回退棧 關系為Test1–>Test2–>Test1

Activity之啟動模式

然後activity棧會移除。

(3)總結:

可以看到進棧時onStop是在下一個activity的onResume建立之後,

出棧時onStop和onDestory在下一個activity的onResume之後

  • singleTop 模式

1、隻修改Test2的啟動模式為singleTop

關系為Test1–>Test2–>Test3–>Test2

activity棧和生命周期等同于standard 模式

2、隻修改Test2的啟動模式為singleTop

關系為Test1–>Test2–>Test3–>Test3

activity棧如下:

Activity之啟動模式

發現目前Test3隻建立了一次,即任務的棧頂正好存在該Activity的執行個體,就重用該執行個體

生命周期如下:

Activity之啟動模式

當啟動模式為singletop時,如果棧頂存在該Activity執行個體就重用,但是不在走onCreate和onStart,走onNewIntent

3、修改Test1、Test2、Test3啟動模式都為singletop

關系為Test1–>Test2–>Test3–>Test1

(1)當正常跳轉,activity棧和生命周期都如standard 模式。

(2)當在Test1頁面按Home鍵退出,然後再點選app圖示進入,生命周期發生變化,如下:

onNewIntent --> onRestart–> onStart–> onResume

(3)當在Test2和Test3頁面按Home鍵退出,然後再點選app圖示進入,生命周期如下:

onRestart–> onStart–> onResume

(注意:standard 模式的生命周期為 onRestart–> onStart–> onResume)

4、總結隻有當棧頂有該activity執行個體,繼續跳轉該activity時才有效,activity棧才不會新增。并且會走onNewIntent和onResume。回退棧跟standard 模式并無差别。(如果該activity跳轉到另一個activity,再跳轉回來時不會走onNewIntent)

  • singleTask 模式

1、隻修改Test1的啟動模式為singleTask

(1)從進入activity --> Home鍵退出 -->手動點選再次進入。生命周期如下:

Activity之啟動模式

可以看出再次進入時會走onNewIntent和onRestart,普通模式隻有onRestart

(因為test1為啟動activity)

2、修改Test2的啟動模式為singleTask,test1和test3的啟動模式為standard

關系為:test1 --> test2 --> test3 --> test2

(1)當test1 --> test2 --> test3時,堆棧關系如下:

Activity之啟動模式

(2)當test3再次跳轉到test2

Activity之啟動模式

(3)最終的生命周期如下:

Activity之啟動模式

可以看見,當test3跳轉到test2時,因為目前是singletask模式,會把它上面的棧的執行個體都會移除。

都為普通模式目前棧:test1–>test2–>test3–>test2。所有移除上面的棧後隻剩下test1–>test2。

  • singleInstance 模式

1、隻修改Test1的啟動模式為singlestance

(1)從進入activity --> Home鍵退出 -->手動點選再次進入。生命周期如下:

Activity之啟動模式

可以看出再次進入時會走onNewIntent和onRestart,普通模式隻有onRestart,跟singletask一緻

2、修改Test2的啟動模式為singleInstance ,test1和test3的啟動模式為standard

關系為:test1 --> test2 --> test3 --> test2

(1)當test1 --> test2 --> test3時,堆棧關系如下:

Activity之啟動模式

即test2是一個單獨配置設定空間,跟test1和test3不在一起。并且test2在下面。

(2)當test3–>test2時

Activity之啟動模式

test2在上面,test1和test3配置設定的棧在下面。

這時的完整生命周期為:

Activity之啟動模式

多混搭模式測試

1、test1為standard、test2為singleInstance、test3為singleTask

(1)當test1 --> test2時,在test2頁面按Home鍵退出,然後再點選圖示進入

------發現驚喜---------

生命周期如下:

Activity之啟動模式

在test2頁面時,test1的生命狀态為onStop,此時按Home鍵退出test2也會進入onStop狀态。但是點選app進入時,出現的是test1的頁面。(很奇怪~)

test1–>test2時的堆棧:

Activity之啟動模式

test2–>按home退出–>app再次進入堆棧

Activity之啟動模式

(2)當test1 --> test2 -->test3,在test3按Home鍵退出,點選app再次進入不會走onNewIntent。

隻有重用該Activity執行個體時才會走onNewIntent。即test3–>test2–>test3

(3)test1–>test2–>test3時,一直按傳回鍵回退,正常回退

2、test1為standard、test2為singleInstance、test3為singleInstance

關系為test1 --> test2 -->test3

Activity之啟動模式

不要以為test2和test3配置設定到同一個空間了,singleinstance單例都是獨立的。

是以按Home鍵退出後,再次進入會進入Test1頁面

3、test1為singleInstance、test2為singleInstance、test3為singleInstance

(1)當test1–>test2或test1–>test2–>test3時,按home鍵退出再進來顯示test1頁面,然後點選回退鍵時,直接退出到桌面。

堆棧如下:

test1–>test2–>test3

Activity之啟動模式

test3–>點選home

Activity之啟動模式

點選app進入

Activity之啟動模式

test2和test3執行個體還在,但是堆棧在系統桌面之下,所有test1回退之後會回到系統桌面。

(2)test1–>test2–>test3時,一直按傳回鍵回退,正常回退

3、test1為singleIntask、test2為singleIntop、test3為singleIntop

(1)當test1–>test2或test1–>test2–>test3時,按home鍵退出,再進來時:

目前堆棧隻剩test1,test2和test3消失

Activity之啟動模式

這時候按傳回鍵退出,test1堆棧消失

Activity之啟動模式

(2)test1–>test2–>test3時,一直按傳回鍵回退,正常回退

(3)test1–>test2–>test3–>test1時,會把test2、test3給移除掉

onNewIntent

1、哪些情況會導緻出現onNewIntent

(1)在啟動模式為singletop時,隻有啟動界面Activity在按Home退出再回到該啟動界面時,會進入

(2)所有Activity啟動模式為singletask時,隻有Activity在按Home退出再回到該啟動界面時,會進入

(3)當啟動界面activity的啟動模式為singleInstance時,無論其他的Activity啟動模式是什麼,按home退出再進入時,會出現并且會回到啟動activity

(4)當啟動模式為singletop、singletask、singleInstance時,目前activity已經在棧頂再次啟動該activity時,會出現

2、容易誤解以為會出現onNewIntent

(1)無論哪種模式,鎖屏再恢複鎖屏都不會進入

(2)無論哪種模式,按傳回鍵都不會進入

(3)連續啟動singletask時,并且啟動界面啟動模式為預設或singletop時,不會進入