我們首先了解下Activity的四種啟動模式分別是:
- standard
標(biāo)準(zhǔn)模式:在不指定啟動模式的前提下,系統(tǒng)默認(rèn)使用該模式啟動Activity饥追,每次啟動一個(gè)Activity都會重寫創(chuàng)建一個(gè)新的實(shí)例,不管這個(gè)實(shí)例存不存在麻惶。
- singleTop
棧頂復(fù)用模式 :如果在任務(wù)的棧頂正好存在該Activity的實(shí)例堕扶, 就重用該實(shí)例,否者就會創(chuàng)建新的實(shí)例并放入棧頂(即使棧中已經(jīng)存在該Activity實(shí)例帅霜,只要不在棧頂,都會創(chuàng)建實(shí)例)呼伸。
- singleTask
棧內(nèi)復(fù)用模式:如果在棧中已經(jīng)有該Activity的實(shí)例身冀,就重用該實(shí)例(會調(diào)用實(shí)例的onNewIntent())。重用時(shí)括享,會讓該實(shí)例回到棧頂搂根,因此在它上面的實(shí)例將會被移除棧。如果棧中不存在該實(shí)例铃辖,將會創(chuàng)建新的實(shí)例放入棧中剩愧。
- singleInstance
單例模式:在一個(gè)新棧中創(chuàng)建該Activity實(shí)例,并讓多個(gè)應(yīng)用共享改棧中的該Activity實(shí)例澳叉。一旦改模式的Activity的實(shí)例存在于某個(gè)棧中,任何應(yīng)用再激活改Activity時(shí)都會重用該棧中的實(shí)例沐悦,其效果相當(dāng)于多個(gè)應(yīng)用程序共享一個(gè)應(yīng)用成洗,不管誰激活該Activity都會進(jìn)入同一個(gè)應(yīng)用中。
其實(shí)上面的解釋誰都會說藏否,但是實(shí)際上我根本不了解瓶殃,或者說我沒有用過這些,我的Activity啟動模式一直是默認(rèn)的副签。所以遥椿,我們在這里會交大家怎么使用它們基矮。
首先,大家在使用它們之前冠场,要考慮個(gè)問題家浇,就是它們?yōu)樯稌霈F(xiàn)?我們?yōu)樯缎枰鼈儯?br>
然后這里跟大家解釋下它們出現(xiàn)的原因:
我們啟動Activity的時(shí)候都是通過startActivity碴裙、startActivityForResult
钢悲,剛開始第一個(gè)Activity
出現(xiàn)也是通過這個(gè)的,不過是隱式調(diào)用罷了舔株。那么這么我們啟動這么Activity
莺琳,總要有個(gè)東西管理它們吧。是的载慈,有一個(gè)工具來管理它們惭等,叫Activity
管理?xiàng)<碩ask來管理它們,這個(gè)棧有什么特點(diǎn)呢办铡?
- 先進(jìn)后出
- 任務(wù)棧內(nèi)的
Activity
清空后才能退出程序
這樣辞做,Task就能管理所有的Activity
的創(chuàng)建和它們的生命周期了,但是這樣又有新的問題出現(xiàn)了料扰。舉例:
我們開始啟動FirstActivity,然后從FIrstActivity跳到SecondActivity凭豪,再從SecondActivity跳到ThirdActivity,現(xiàn)在我們要返回FirstActivity.這時(shí)我們不能直接
startActivity(new Intent(ThirdActivity.this,FirstActivity.class))
,為什么晒杈,因?yàn)檫@樣會創(chuàng)建一個(gè)新的FirstActivity嫂伞。所有我們只能在ThirdActivity中finish()
,然后在SecondActivity中的onActivityResult()
方法中再finish()
,這樣才返回到了FirstActivity。大家發(fā)現(xiàn)了拯钻,這樣很麻煩帖努。假設(shè)你不需要返回剛開始FIrstActivity的實(shí)例,新創(chuàng)建也沒關(guān)系粪般。我就喜歡直接startActivity
跳過去拼余。這樣的話,新的問題又產(chǎn)生了亩歹,如果你要退出程序怎么辦匙监?我們退出程序一般是按返回鍵退出的。你一直按back
返回鍵的話小作,它會先跳到FirstActivity,然后再到SecondActivity亭姥,再到FirstActivity,這樣才能退出顾稀,這樣是不是很麻煩达罗,而且用戶體驗(yàn)也很不好。
所以静秆,這個(gè)使用我們尋找一種解決方法粮揉,解決上訴的問題巡李。于是,Google提出了Activity
的四種啟動模式扶认。我們現(xiàn)在來分析下四種啟動模式侨拦。
Standard
Activity
的啟動模式為standard
的時(shí)候,每次startActivity
時(shí)都會產(chǎn)生一個(gè)新的對象蝠引,就和我們A a = new A()
是一樣的阳谍。
SignleTop
當(dāng)
Activity
的啟動模式為signleTop
的時(shí)候,但它處于棧頂?shù)臅r(shí)候螃概,說的清楚點(diǎn)矫夯,就是當(dāng)前頁面現(xiàn)實(shí)的Activity
為它的時(shí)候,startActivity
的時(shí)候跳到的是本對象吊洼。如果當(dāng)前對象不是它本身的時(shí)候训貌,它和standard
是一樣的。那么這樣的話它有啥作用呢冒窍?還是舉個(gè)例子:比如你點(diǎn)美團(tuán)外賣的時(shí)候递沪,手機(jī)會收到外賣的進(jìn)度情況,如果你點(diǎn)擊了一條通知综液,然后會進(jìn)去一個(gè)外賣訂單進(jìn)度顯示的界面款慨,如下:
這時(shí),外賣訂單信息跟新了谬莹,你點(diǎn)擊更新的信息檩奠,就會直接進(jìn)去改頁面,然后訂單信息跟新附帽,這時(shí)沒有跳轉(zhuǎn)新的頁面埠戳。不知道這時(shí)你是否考慮到一個(gè)問題?如果沒有跳轉(zhuǎn)界面蕉扮,那么我在哪兒獲取Intent
的消息?當(dāng)然有方法獲取整胃,這時(shí)會在onNewIntent(Intent intent)
這個(gè)方法中獲取Intent
,就不能在生命周期中獲取getIntent
,切記!
SignleTask
Activity
的啟動模式為SignleTask
的時(shí)候,不管怎樣跳轉(zhuǎn)到本Activity
的時(shí)候喳钟,那么任務(wù)棧Task就會把它頂?shù)綏m斊ㄊ埂_@么說比較抽象,那么還是舉例子說明吧奔则。我們先來看上面例子中我么遇到的問題:我們開始啟動FirstActivity,然后從FIrstActivity跳到SecondActivity蛮寂,再從SecondActivity跳到ThirdActivity,現(xiàn)在我們要返回FirstActivity应狱。上面已經(jīng)說了共郭,我么不能在ThirdActivity中直接startActivity()
,因?yàn)檫@樣會產(chǎn)生新的實(shí)例祠丝,而且退出的時(shí)候很麻煩疾呻。那么當(dāng)我們的FIrstActivity的啟動模式為signleTask
的時(shí)候除嘹,我們就可以直接這樣用了。因?yàn)槿蝿?wù)棧Task不是產(chǎn)生新的FirstActivity
,而是會把FirstActivity和ThirdActivity中間的Activity全部finish
掉岸蜗,這樣FirstActivity就會在棧頂了尉咕,跟我們手動finish()
作用一樣的。當(dāng)然璃岳,傳遞消息也不是走生命周期年缎,也是走OnNewIntent(Intent intent)
方法。這里也說下它的作用铃慷,一般它為程序的主界面单芜,即MainActivity
,為什么呢犁柜?因?yàn)檫@樣不管從哪個(gè)Activity
返回主界面的時(shí)候直接startActivity
就行洲鸠,而且保證主界面的唯一性。
SignleInstance
這種啟動模式馋缅,一般很少見或者很少用扒腕。為什么呢?因?yàn)樗且粋€(gè)單例萤悴。我還是來舉例說明吧瘾腰!我們把FirstActivity的啟動模式設(shè)置為
signleTask
,SecondActivity的啟動模式為standard
,ThirdActivity的啟動模式為signleInstance
覆履,這樣我們啟動FirstActivity的時(shí)候系統(tǒng)會自動創(chuàng)建一個(gè)任務(wù)棧Task1蹋盆,然后將FirstActivity加入Task1中,跳轉(zhuǎn)到SecondActivity的時(shí)候也會將SecondActivity加入到Task1中内狗,但是跳轉(zhuǎn)到ThirdActivity的時(shí)候系統(tǒng)會創(chuàng)建一個(gè)任務(wù)棧Task2怪嫌,然后將ThirdActivity加入到Task2中,而且Task2只會存在一個(gè)Activity
柳沙。因?yàn)門ask2只有一個(gè)ThirdActivity
,所以ThirdActivity永遠(yuǎn)處于棧頂岩灭,如果不主動finish()
掉的話,第二次跳轉(zhuǎn)到ThirdActivity的時(shí)候赂鲤,也是通過OnNewIntent(Intent intent)
獲取傳遞消息的噪径。但是記住一個(gè)問題,不要把signleInstance
模式的Activity
作為中轉(zhuǎn)站数初,這樣的話系統(tǒng)會把Task2做默認(rèn)的任務(wù)棧找爱,推出程序時(shí)會先跳到Task2再退出程序。作用的話泡孩,還是舉例說明吧车摄!比如A、B、C吮播、D四個(gè)Activity
变屁,我希望從A→D,B→D,C→D,或者A→B→D等的時(shí)候意狠,D永遠(yuǎn)只有一個(gè)粟关,但是又不會像signleTask
把中間的Activity
全部finish()
掉,這樣D就不能和A环戈、B闷板、C在同一個(gè)Task里,就可以把D的啟動模式設(shè)置為signleInstance
院塞。