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)模式棒厘。