1.問(wèn)題描述
今天碰到了一個(gè)問(wèn)題,當(dāng)一個(gè)Activity的啟動(dòng)模式為SingleTask的時(shí)候,Activity間進(jìn)行跳轉(zhuǎn)的時(shí)候,在該Activity的onCreate()方法里接收不到Bundle攜帶過(guò)來(lái)的值,通過(guò)這個(gè)小問(wèn)題也讓我明白了學(xué)習(xí)啟動(dòng)模式的重要性。
在解決這個(gè)問(wèn)題之前,我們先來(lái)看一種情況,假設(shè)現(xiàn)在有ABCDE五個(gè)ActivIty,只有B的啟動(dòng)模式是singleTask,其余Activty是標(biāo)準(zhǔn)模式,Activity跳轉(zhuǎn)的順序是ABCDEAB,問(wèn)現(xiàn)在棧中還有那幾個(gè)Activity,知道singleTask原理的小伙伴們很容易知答案是A和B。
2.找原因
我們先來(lái)對(duì)比一下,standard標(biāo)準(zhǔn)模式和 singleTask 棧內(nèi)復(fù)用模式:
1.如果ABCDE這五個(gè)Activity都是標(biāo)準(zhǔn)啟動(dòng)模式,那依次執(zhí)行完跳轉(zhuǎn)Activity:ABCDEAB,棧內(nèi)的情況是這樣的:

標(biāo)準(zhǔn)啟動(dòng)模式也是系統(tǒng)默認(rèn)的啟動(dòng)模式,每啟動(dòng)一個(gè)Activity,都會(huì)重新創(chuàng)建一個(gè)實(shí)例,不管這個(gè)實(shí)例是否存在,并且我們知道任務(wù)棧是"先進(jìn)后出的",所以先進(jìn)棧的A位于棧底,最后一個(gè)Activity B位于棧頂。
2.當(dāng)B Acticity的啟動(dòng)模式是singleTask 棧內(nèi)復(fù)用模式時(shí)候,棧內(nèi)的情況是這樣的:

因?yàn)锽 的實(shí)例在棧內(nèi)存在,所以再次啟動(dòng)的時(shí)候,就不會(huì)重新創(chuàng)建實(shí)例了,所以B 回到棧頂,并且B 上面的 實(shí)例會(huì)被移出棧,最終任務(wù)棧內(nèi)的情況是這樣的:

回到我開頭說(shuō)的那個(gè)問(wèn)題,啟動(dòng)一個(gè) 啟動(dòng)模式為 SingleTask 的Activity,為什么會(huì)在onCreate()方法里,拿不到Bundle傳遞的值?
原因也很簡(jiǎn)單,假設(shè)在任務(wù)棧中存在該Activity的實(shí)例,再次啟動(dòng)的時(shí)候,也就不會(huì)重新去創(chuàng)建它的實(shí)例,onCreate方法并沒有執(zhí)行,也就獲取不到Bundle傳遞過(guò)來(lái)的值。此時(shí),我們需要重寫 onNewIntent()方法,系統(tǒng)會(huì)回調(diào)其onNewIntent方法,并將 onNewIntent 接收的 intent設(shè)置給 Activity。之后,我們可以在 onStart()方法中接收Bundle傳遞過(guò)來(lái)的值。

假設(shè)任務(wù)棧內(nèi)不存在該Activity的實(shí)例,就會(huì)重新創(chuàng)建,其生命周期方法onCreate(),onStart(),onResume() 都會(huì)正常執(zhí)行。
3.感悟
Activity作為四大組件之一,其重要性不言而喻,除了生命周期之外,它的啟動(dòng)模式也是一個(gè)重點(diǎn)和難點(diǎn),找工作面試被問(wèn)的概率還是很大,當(dāng)然更重要的是,我們?nèi)粘i_發(fā)工作的時(shí)候,為了滿足某些項(xiàng)目的特殊需求,就必須使用到Activity的啟動(dòng)模式,所以我們必須要掌握其四種啟動(dòng)模式。