在一個(gè)項(xiàng)目中會(huì)包括著多個(gè)Activity肠阱,系統(tǒng)中使用任務(wù)棧來(lái)存儲(chǔ)創(chuàng)建的Activity實(shí)例饥臂,任務(wù)棧是一種“后進(jìn)先出”的棧結(jié)構(gòu)。舉個(gè)栗子茅信,若我們多次啟動(dòng)同一個(gè)Activity盾舌。系統(tǒng)會(huì)創(chuàng)建多個(gè)實(shí)例依次放入任務(wù)棧中。當(dāng)按back鍵返回時(shí)蘸鲸,每按一次妖谴,一個(gè)Activity出棧,直到椬靡。空為止膝舅。當(dāng)棧中無(wú)不論什么Activity。系統(tǒng)就會(huì)回收此任務(wù)棧窑多。
上面這個(gè)樣例中的Activity并沒(méi)有設(shè)置啟動(dòng)模式仍稀,你會(huì)發(fā)現(xiàn)多次啟動(dòng)同一個(gè)Activity。而系統(tǒng)卻創(chuàng)建了多個(gè)實(shí)例埂息,白白浪費(fèi)內(nèi)存技潘,這樣的情況Android早就替我們考慮好了遥巴。Android為Activity 的創(chuàng)建提供了4種啟動(dòng)模式,而依據(jù)實(shí)際應(yīng)用場(chǎng)景的不同享幽。為Activity 選擇不同的啟動(dòng)模式铲掐,最大化降低了每次都須要在棧中創(chuàng)建一個(gè)新的Activity的壓力,降低內(nèi)存使用值桩。
啟動(dòng)模式的具體說(shuō)明和使用場(chǎng)景摆霉?以下依據(jù)這篇博文來(lái)一一解惑。
standard 模式
這是默認(rèn)模式奔坟,每次激活A(yù)ctivity時(shí)都會(huì)創(chuàng)建Activity實(shí)例携栋,并放入任務(wù)棧中。使用場(chǎng)景:大多數(shù)Activity蛀蜜。
singleTop 模式
如果在任務(wù)的棧頂正好存在該Activity的實(shí)例刻两,就重用該實(shí)例( 會(huì)調(diào)用實(shí)例的 onNewIntent() )增蹭,否則就會(huì)創(chuàng)建新的實(shí)例并放入棧頂滴某,即使棧中已經(jīng)存在該Activity的實(shí)例,只要不在棧頂滋迈,都會(huì)創(chuàng)建新的實(shí)例霎奢。使用場(chǎng)景如新聞?lì)惢蛘唛喿x類App的內(nèi)容頁(yè)面。
singleTask 模式
如果在棧中已經(jīng)有該Activity的實(shí)例饼灿,就重用該實(shí)例(會(huì)調(diào)用實(shí)例的 onNewIntent() )幕侠。重用時(shí),會(huì)讓該實(shí)例回到棧頂碍彭,因此在它上面的實(shí)例將會(huì)被移出棧晤硕。如果棧中不存在該實(shí)例,將會(huì)創(chuàng)建新的實(shí)例放入棧中庇忌。使用場(chǎng)景如瀏覽器的主界面舞箍。不管從多少個(gè)應(yīng)用啟動(dòng)瀏覽器,只會(huì)啟動(dòng)主界面一次皆疹,其余情況都會(huì)走onNewIntent疏橄,并且會(huì)清空主界面上面的其他頁(yè)面。
singleInstance 模式
在一個(gè)新棧中創(chuàng)建該Activity的實(shí)例略就,并讓多個(gè)應(yīng)用共享該棧中的該Activity實(shí)例捎迫。一旦該模式的Activity實(shí)例已經(jīng)存在于某個(gè)棧中,任何應(yīng)用再激活該Activity時(shí)都會(huì)重用該棧中的實(shí)例( 會(huì)調(diào)用實(shí)例的 onNewIntent() )表牢。其效果相當(dāng)于多個(gè)應(yīng)用共享一個(gè)應(yīng)用窄绒,不管誰(shuí)激活該 Activity 都會(huì)進(jìn)入同一個(gè)應(yīng)用中。使用場(chǎng)景如鬧鈴提醒崔兴,將鬧鈴提醒與鬧鈴設(shè)置分離彰导。singleInstance不要用于中間頁(yè)面浊闪,如果用于中間頁(yè)面,跳轉(zhuǎn)會(huì)有問(wèn)題螺戳,比如:A -> B (singleInstance) -> C搁宾,完全退出后,在此啟動(dòng)倔幼,首先打開(kāi)的是B盖腿。
一. Android啟動(dòng)模式具體解釋
1. Standard 標(biāo)準(zhǔn)模式
說(shuō)明:?Android創(chuàng)建Activity時(shí)的默認(rèn)模式,假設(shè)沒(méi)有為Activity設(shè)置啟動(dòng)模式的話损同,默覺(jué)得標(biāo)準(zhǔn)模式翩腐。每次啟動(dòng)一個(gè)Activity都會(huì)又一次創(chuàng)建一個(gè)新的實(shí)例入棧,無(wú)論這個(gè)實(shí)例是否存在膏燃。
生命周期:如上所看到的茂卦,每次被創(chuàng)建的實(shí)例Activity 的生命周期符合典型情況,它的onCreate、onStart、onResume都會(huì)被調(diào)用伶棒。
舉例:此時(shí)Activity 棧中以此有A伊者、B、C三個(gè)Activity,此時(shí)C處于棧頂,啟動(dòng)模式為Standard 模式。
若在C Activity中加入點(diǎn)擊事件泥畅,須要跳轉(zhuǎn)到還有一個(gè)同類型的C Activity。結(jié)果是還有一個(gè)C Activity進(jìn)入棧中琅翻,成為棧頂位仁。?
2. SingleTop 棧頂復(fù)用模式
說(shuō)明:分兩種處理情況:須要?jiǎng)?chuàng)建的Activity已經(jīng)處于棧頂時(shí),此時(shí)會(huì)直接復(fù)用棧頂?shù)腁ctivity方椎。不會(huì)再創(chuàng)建新的Activity聂抢;若須要?jiǎng)?chuàng)建的Activity不處于棧頂,此時(shí)會(huì)又一次創(chuàng)建一個(gè)新的Activity入棧辩尊,同Standard模式一樣涛浙。
生命周期:若情況一中棧頂?shù)腁ctivity被直接復(fù)用時(shí),它的onCreate摄欲、onStart不會(huì)被系統(tǒng)調(diào)用轿亮,由于它并沒(méi)有發(fā)生改變⌒厍剑可是一個(gè)新的方法?onNewIntent會(huì)被回調(diào)(Activity被正常創(chuàng)建時(shí)不會(huì)回調(diào)此方法)我注。
舉例:此時(shí)Activity 棧中以此有A、B迟隅、C三個(gè)Activity但骨,此時(shí)C處于棧頂励七,啟動(dòng)模式為SingleTop 模式。情況一:在C Activity中加入點(diǎn)擊事件奔缠,須要跳轉(zhuǎn)到還有一個(gè)同類型的C Activity掠抬。
結(jié)果是直接復(fù)用棧頂?shù)腃 Activity。
情況二:在C Activity中加入點(diǎn)擊事件校哎,須要跳轉(zhuǎn)到還有一個(gè)A Activity两波。結(jié)果是創(chuàng)建一個(gè)新的Activity入棧。成為棧頂闷哆。
3. SingleTask 棧內(nèi)復(fù)用模式
說(shuō)明:若須要?jiǎng)?chuàng)建的Activity已經(jīng)處于棧中時(shí)腰奋,此時(shí)不會(huì)創(chuàng)建新的Activity,而是將存在棧中的Activity上面的其他Activity所有銷毀抱怔,使它成為棧頂劣坊。
生命周期:同SingleTop 模式中的情況一同樣。僅僅會(huì)又一次回調(diào)Activity中的?onNewIntent方法
舉例:此時(shí)Activity 棧中以此有A屈留、B局冰、C三個(gè)Activity。此時(shí)C處于棧頂绕沈,啟動(dòng)模式為SingleTask 模式锐想。
情況一:在C Activity中加入點(diǎn)擊事件帮寻,須要跳轉(zhuǎn)到還有一個(gè)同類型的C Activity乍狐。結(jié)果是直接用棧頂?shù)腃 Activity。情況二:在C Activity中加入點(diǎn)擊事件固逗,須要跳轉(zhuǎn)到還有一個(gè)A Activity浅蚪。
結(jié)果是將A Activity上面的B、C所有銷毀烫罩,使A Activity成為棧頂惜傲。?
4. SingleInstance 單實(shí)例模式
說(shuō)明:?SingleInstance比較特殊,是全局單例模式贝攒,是一種加強(qiáng)的SingleTask模式盗誊。它除了具有它所有特性外,還加強(qiáng)了一點(diǎn):具有此模式的Activity僅僅能單獨(dú)位于一個(gè)任務(wù)棧中隘弊。
這個(gè)經(jīng)常使用于系統(tǒng)中的應(yīng)用哈踱,比如Launch、鎖屏鍵的應(yīng)用等等梨熙,整個(gè)系統(tǒng)中僅僅有一個(gè)开镣!所以在我們的應(yīng)用中一般不會(huì)用到。了解就可以咽扇。
舉例:比方 A Activity是該模式邪财,啟動(dòng)A后陕壹。系統(tǒng)會(huì)為它創(chuàng)建一個(gè)單獨(dú)的任務(wù)棧,由于棧內(nèi)復(fù)用的特性树埠。興許的請(qǐng)求均不會(huì)創(chuàng)建新的Activity糠馆,除非這個(gè)獨(dú)特的任務(wù)棧被系統(tǒng)銷毀。
二.啟動(dòng)模式的使用方式
1. 在 Manifest.xml中指定Activity啟動(dòng)模式
一種靜態(tài)的指定方法怎憋,在Manifest.xml文件里聲明Activity的同一時(shí)候指定它的啟動(dòng)模式榨惠,這樣在代碼中跳轉(zhuǎn)時(shí)會(huì)依照指定的模式來(lái)創(chuàng)建Activity。樣例例如以下:
2. 啟動(dòng)Activity時(shí)盛霎。在Intent中指定啟動(dòng)模式去創(chuàng)建Activity
一種動(dòng)態(tài)的啟動(dòng)模式赠橙,在new 一個(gè)Intent后,通過(guò)Intent的addFlags方法去動(dòng)態(tài)指定一個(gè)啟動(dòng)模式愤炸。樣例例如以下:
Intent intent = new Intent();intent.setClass(context, MainActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);
注意:以上兩種方式都能夠?yàn)锳ctivity指定啟動(dòng)模式期揪,可是二者還是有差別的。
(1)優(yōu)先級(jí):動(dòng)態(tài)指定方式即另外一種比第一種優(yōu)先級(jí)要高规个,若兩者同一時(shí)候存在凤薛,以另外一種方式為準(zhǔn)。
(2)限定范圍:第一種方式無(wú)法為Activity直接指定?FLAG_ACTIVITY_CLEAR_TOP?標(biāo)識(shí)诞仓,另外一種方式無(wú)法為Activity指定?singleInstance?模式缤苫。
三. Activity 的 Flags
標(biāo)記位既能夠設(shè)定Activity的啟動(dòng)模式,如同上面介紹的墅拭,在動(dòng)態(tài)指定啟動(dòng)模式活玲,比方?FLAG_ACTIVITY_NEW_TASK?和FLAG_ACTIVITY_SINGLE_TOP?等。它還能夠影響Activity 的運(yùn)行狀態(tài) 谍婉,比方?FLAG_ACTIVITY_CLEAN_TOP?和?FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS?等舒憾。
以下介紹幾個(gè)基本的標(biāo)記位,切勿死記穗熬,理解幾個(gè)就可以镀迂,須要時(shí)再查官方文檔。
1. FLAG_ACTIVITY_NEW_TASK
作用是為Activity指定 “SingleTask”啟動(dòng)模式唤蔗。跟在AndroidMainfest.xml指定效果同樣探遵。
2. FLAG_ACTIVITY_SINGLE_TOP
作用是為Activity指定 “SingleTop”啟動(dòng)模式,跟在AndroidMainfest.xml指定效果同樣妓柜。
3. FLAG_ACTIVITY_CLEAN_TOP
具有此標(biāo)記位的Activity箱季,啟動(dòng)時(shí)會(huì)將與該Activity在同一任務(wù)棧的其他Activity出棧。一般與SingleTask啟動(dòng)模式一起出現(xiàn)领虹。它會(huì)完畢SingleTask的作用规哪。但事實(shí)上SingleTask啟動(dòng)模式默認(rèn)具有此標(biāo)記位的作用
4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
具有此標(biāo)記位的Activity不會(huì)出如今歷史Activity的列表中,使用場(chǎng)景:當(dāng)某些情況下我們不希望用戶通過(guò)歷史列表回到Activity時(shí)塌衰,此標(biāo)記位便體現(xiàn)了它的效果诉稍。它等同于在xml中指定Activity的屬性:
android:excludeFromRecents="trure"
四. 啟動(dòng)模式的實(shí)際應(yīng)用場(chǎng)景
這四種模式中的Standard模式是最普通的一種蝠嘉,沒(méi)有什么特別注意。而SingleInstance模式是整個(gè)系統(tǒng)的單例模式杯巨,在我們的應(yīng)用中一般不會(huì)應(yīng)用到蚤告。所以,這里就具體解說(shuō)?SingleTop?和?SingleTask模式的運(yùn)用場(chǎng)景:
1. SingleTask模式的運(yùn)用場(chǎng)景
最常見(jiàn)的應(yīng)用場(chǎng)景就是保持我們應(yīng)用開(kāi)啟后僅僅有一個(gè)Activity的實(shí)例服爷。最典型的樣例就是應(yīng)用中展示的主頁(yè)(Home頁(yè))杜恰。
假設(shè)用戶在主頁(yè)跳轉(zhuǎn)到其他頁(yè)面,運(yùn)行多次操作后想返回到主頁(yè)仍源,假設(shè)不使用SingleTask模式心褐,在點(diǎn)擊返回的過(guò)程中會(huì)多次看到主頁(yè),這明顯就是設(shè)計(jì)不合理了笼踩。
2. SingleTop模式的運(yùn)用場(chǎng)景
假設(shè)你在當(dāng)前的Activity中又要啟動(dòng)同類型的Activity逗爹,此時(shí)建議將此類型Activity的啟動(dòng)模式指定為SingleTop,能夠降低Activity的創(chuàng)建嚎于,節(jié)省內(nèi)存掘而!
3. 注意:復(fù)用Activity時(shí)的生命周期回調(diào)
這里還須要考慮一個(gè)Activity跳轉(zhuǎn)時(shí)攜帶頁(yè)面參數(shù)的問(wèn)題。
由于當(dāng)一個(gè)Activity設(shè)置了SingleTop或者SingleTask模式后于购,跳轉(zhuǎn)此Activity出現(xiàn)復(fù)用原有Activity的情況時(shí)袍睡,此Activity的onCreate方法將不會(huì)再次運(yùn)行。onCreate方法僅僅會(huì)在第一次創(chuàng)建Activity時(shí)被運(yùn)行肋僧。
而一般onCreate方法中會(huì)進(jìn)行該頁(yè)面的數(shù)據(jù)初始化斑胜、UI初始化,假設(shè)頁(yè)面的展示數(shù)據(jù)無(wú)關(guān)頁(yè)面跳轉(zhuǎn)傳遞的參數(shù)色瘩,則不必操心此問(wèn)題伪窖,若頁(yè)面展示的數(shù)據(jù)就是通過(guò)getInten() 方法來(lái)獲取,那么問(wèn)題就會(huì)出現(xiàn):getInten()獲取的一直都是老數(shù)據(jù)居兆,根本無(wú)法接收跳轉(zhuǎn)時(shí)傳送的新數(shù)據(jù)!
以下竹伸,通過(guò)一個(gè)樣例來(lái)具體解釋:
Manifest.xml
publicclassCourseDetailActivityextendsBaseActivity{......@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_course_detail_layout);? ? ? ? initData();? ? ? ? initView();? ? }//初始化數(shù)據(jù)privatevoidinitData() {? ? ? ? Intent intent = getIntent();? ? ? ? mCourseID = intent.getStringExtra(COURSE_ID);? ? }//初始化UIprivatevoidinitView() {? ? ......? ? }? ? ......}
以上代碼中的CourseDetailActivity在配置文件里設(shè)置了啟動(dòng)模式是SingleTop模式泥栖,依據(jù)上面啟動(dòng)模式的介紹可得知,當(dāng)CourseDetailActivity處于棧頂時(shí)勋篓。再次跳轉(zhuǎn)頁(yè)面到CourseDetailActivity時(shí)會(huì)直接復(fù)用原有的Activity吧享,并且此頁(yè)面須要展示的數(shù)據(jù)是從getIntent()方法得來(lái),可是initData()方法不會(huì)再次被調(diào)用譬嚣,此時(shí)頁(yè)面就無(wú)法顯示新的數(shù)據(jù)钢颂。
當(dāng)然這樣的情況系統(tǒng)早就為我們想過(guò)了,這時(shí)我們須要另外一個(gè)回調(diào) onNewIntent(Intent intent)方法拜银。此方法會(huì)傳入最新的intent殊鞭,這樣我們就能夠解決上述問(wèn)題遭垛。這里建議的方法是又一次去setIntent。然后又一次去初始化數(shù)據(jù)和UI操灿。代碼例如以下所看到的:
/*
* 復(fù)用Activity時(shí)的生命周期回調(diào)
*/@OverrideprotectedvoidonNewIntent(Intent intent) {super.onNewIntent(intent);? ? ? ? setIntent(intent);? ? ? ? initData();? ? ? ? initView();? ? }
這樣锯仪,在一個(gè)頁(yè)面中能夠反復(fù)跳轉(zhuǎn)并顯示不同的內(nèi)容。
轉(zhuǎn)自:https://www.cnblogs.com/claireyuancy/p/7387696.html