Activity的完整生命週期以下圖:html
Activity的加載模式有四種:程序員
standard: 標準模式,默認的加載模式,每次經過這種模式啓動目標Acitivity,都建立一個新的實例,並將該Activity添加到當前棧中。編程
singleTop: 與標準模式相似,只有當Activity位於Task頂時,系統不會從新建立目標Activity的示例,而是直接複用已有的Activity實例。架構
singleTask: 函數
若是要啓動的Activity不存在,系統建立Activity實例,並將它加入棧頂網站
若是將啓動的Activity存在,已經位於棧頂,此時與singleTop行爲相同spa
若是要啓動的Activity存在,但不是位於棧頂,系統會使Activity上面全部的Activity出棧。rest
singleInstance:code
若是要啓動的Activity不存在,系統會建立一個新的Task,再建立Activity實例,將它加入新Task的棧頂orm
若是要啓動的Activity存在,不管它在哪一個應用程序中,系統都會把該Activity所在的Task轉至前臺。
下面依次驗證,再四種加載模式下,Activity的各生命週期如何執行。假設有Activity A,B,C
一、標準模式啓動A->B->C
//啓動AD/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume//啓動BD/activityA(19864): onPause D/activityB(19864): onCreate D/activityB(19864): onStart D/activityB(19864): onResume D/activityA(19864): onStop//啓動CD/activityB(19864): onPause D/activityC(19864): onCreate D/activityC(19864): onStart D/activityC(19864): onResume D/activityB(19864): onStop
而後按返回建:
D/activityC(19864): onPause D/activityB(19864): onRestart D/activityB(19864): onStart D/activityB(19864): onResume D/activityC(19864): onStop D/activityC(19864): onDestory
因此若是未調用onDestory從新啓動的話,不會調用onCreate,而是會調用onRestart。
二、A->B->A
D/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume D/activityA(19864): onPause D/activityB(19864): onCreate D/activityB(19864): onStart D/activityB(19864): onResume D/activityA(19864): onStop D/activityB(19864): onPause D/activityA(19864): onCreate D/activityA(19864): onStart D/activityA(19864): onResume D/activityB(19864): onStop
修改A的啓動模式爲singleTop
->A->A
D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityA(27075): onPause D/activityA(27075): onNewIntent D/activityA(27075): onResume
->A->B->A
D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityA(27075): onPause D/activityB(27075): onCreate D/activityB(27075): onStart D/activityB(27075): onResume D/activityA(27075): onStop D/activityB(27075): onPause D/activityA(27075): onCreate D/activityA(27075): onStart D/activityA(27075): onResume D/activityB(27075): onStop
當A不是棧頂時,啓動A,又從新建立了A,並且觀察以上輸出,兩個Activity切換時,首先當前Activity先onPause,而後被啓動的Activity,依次onCreate, onStart, onResume顯示出來以後,以前的Activity纔會onStop。
修改A的啓動方式爲singleTask,
->A->A
D/activityA( 2744): onCreate D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityA( 2744): onPause D/activityA( 2744): onNewIntent D/activityA( 2744): onResume
當A不存在時,建立A,當A存在且在棧頂時,先onPause,而後onNewIntent,以後onResume。
->A->B->A
D/activityA( 2744): onCreate D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityA( 2744): onPause D/activityB( 2744): onCreate D/activityB( 2744): onStart D/activityB( 2744): onResume D/activityA( 2744): onStop D/activityB( 2744): onPause D/activityA( 2744): onNewIntent D/activityA( 2744): onRestart D/activityA( 2744): onStart D/activityA( 2744): onResume D/activityB( 2744): onStop D/activityB( 2744): onDestory
能夠看到第二次啓動A後,A調用了onNewIntent,onRestart,onStart,onResume,關鍵是以後調了B的onStop, onDestory,在以前的兩種模式下只是另B,調用了onStop,因此推斷,singleTask時,是以前的A經過onNewIntent從新進入onResume,而後將B移除出了棧。
修改A的啓動方式爲SingleInstance
->A->A
D/activityA(10578): onCreate D/activityA(10578): onStart D/activityA(10578): onResume D/activityA(10578): onPause D/activityA(10578): onNewIntent D/activityA(10578): onResume
與singleTask表現一致
->A->B->A
D/activityA(10578): onCreate D/activityA(10578): onStart D/activityA(10578): onResume D/activityA(10578): onPause D/activityB(10578): onCreate D/activityB(10578): onStart D/activityB(10578): onResume D/activityA(10578): onStop D/activityB(10578): onPause D/activityA(10578): onNewIntent D/activityA(10578): onRestart D/activityA(10578): onStart D/activityA(10578): onResume D/activityB(10578): onStop
在singleInstance模式下,複用了原來的A,對B只是onStop,並無發生出棧銷燬。
總結以上:
當複用一個已經存在的Activity時,一般是從它的onNewIntent或onRestart開始調起,
若是一個Activity要出棧,必然會調到onDestory
在兩個Activity切換的過程當中,是當前的Activity先onPause,而後讓新的Activity建立或者restart,知道onResume,前一個Activity纔會走onStop以及onDestory
另一個問題:分別在A生命週期函數內啓動B(A,B都是Standared),
D/activityA(17860): onCreate D/activityA(17860): onStart D/activityA(17860): onResume D/activityA(17860): onPause D/activityB(17860): onCreate D/activityB(17860): onStart D/activityB(17860): onResume D/activityA(17860): onStop
生命週期的回調函數是完整的,都會依次調到,可是有個問題是當按back鍵後,會出現以下:
D/activityB(19588): onPause D/activityA(19588): onRestart D/activityA(19588): onStart D/activityA(19588): onResume D/activityA(19588): onPause D/activityB(19588): onCreate D/activityB(19588): onStart D/activityB(19588): onResume D/activityB(19588): onStop D/activityB(19588): onDestory D/activityA(19588): onStop
須要返回A,可是A在啓動的生命週期中又啓動了B,這時的行爲就跟啓動模式有關了,老是它正常切換時正確的執行順序。
這個知識點太繞了,其實萬變不離其宗,都是四種啓動模式生命週期執行順序的組合。
問啊APP,程序員答題神器,解決你全部的技術難題, (上問啊APP 瞭解更多) http://t.cn/R4vE2d7 下載註冊送5元 快去下載註冊吧!
問啊-定製化IT教育平臺,牛人一對一服務,有問必答,開發編程社交頭條 官方網站:www.wenaaa.com 下載問啊APP,參與官方懸賞,賺百元現金。
QQ羣290551701 彙集不少互聯網精英,技術總監,架構師,項目經理!開源技術研究,歡迎業內人士,大牛及新手有志於從事IT行業人員進入!