發(fā)表于 2014-7-16 11:47 | 來自 51CTO網(wǎng)頁 [只看他] 樓主
小編最近遇到了activity經(jīng)常跳轉(zhuǎn)棧溢出的問題看了老羅的神一樣的“singleTask”之后深有體會,,并做總結(jié)如下:
【原】Activity有四種加載模式:standard(默認),, singleTop,, singleTask和 singleInstance。以下逐一舉例說明他們的區(qū)別,。 standard:Activity的默認加載方法,,即使某個Activity在 Task棧中已經(jīng)存在,另一個activity通過Intent跳轉(zhuǎn)到該activity,,同樣會新創(chuàng)建一個實例壓入棧中,。例如:現(xiàn)在棧的情況為:A B C D,在D這個Activity中通過Intent跳轉(zhuǎn)到D,,那么現(xiàn)在的棧情況為: A B C D D ,。此時如果棧頂?shù)腄通過Intent跳轉(zhuǎn)到B,,則棧情況為:A B C D D B。此時如果依次按返回鍵,,D D C B A將會依次彈出棧而顯示在界面上,。 singleTop:如果某個Activity的Launch mode設(shè)置成singleTop,那么當該Activity位于棧頂?shù)臅r候,,再通過Intent跳轉(zhuǎn)到本身這個Activity,,則將不會創(chuàng)建一個新的實例壓入棧中。例如:現(xiàn)在棧的情況為:A B C D,。D的Launch mode設(shè)置成了singleTop,,那么在D中啟動Intent跳轉(zhuǎn)到D,那么將不會新創(chuàng)建一個D的實例壓入棧中,,此時棧的情況依然為:A B C D,。但是如果此時B的模式也是singleTop,D跳轉(zhuǎn)到B,,那么則會新建一個B的實例壓入棧中,,因為此時B不是位于棧頂,此時棧的情況就變成了:A B C D B,。 singleTask:如果某個Activity是singleTask模式,,那么Task棧中將會只有一個該Activity的實例。例如:現(xiàn)在棧的情況為:A B C D,。B的Launch mode為singleTask,,此時D通過Intent跳轉(zhuǎn)到B,則棧的情況變成了:A B,。而C和D被彈出銷毀了,,也就是說位于B之上的實例都被銷毀了。 singleInstance:將Activity壓入一個新建的任務(wù)棧中,。例如:Task棧1的情況為:A B C,。C通過Intent跳轉(zhuǎn)到D,而D的Launch mode為singleInstance,,則將會新建一個Task棧2,。此時Task棧1的情況還是為:A B C。Task棧2的情況為:D,。此時屏幕界面顯示D的內(nèi)容,,如果這時D又通過Intent跳轉(zhuǎn)到D,則Task棧2中也不會新建一個D的實例,,所以兩個棧的情況也不會變化,。而如果D跳轉(zhuǎn)到C,則棧1的情況變成了:A B C C,,因為C的Launch mode為standard,,此時如果再按返回鍵,,則棧1變成:A B C。也就是說現(xiàn)在界面還顯示C的內(nèi)容,,不是D,。 Intent的常用Flag參數(shù): FLAG_ACTIVITY_CLEAR_TOP:例如現(xiàn)在的棧情況為:A B C D 。D此時通過intent跳轉(zhuǎn)到B,,如果這個intent添加FLAG_ACTIVITY_CLEAR_TOP 標記,,則棧情況變?yōu)椋篈 B。如果沒有添加這個標記,,則棧情況將會變成:A B C D B,。也就是說,如果添加了FLAG_ACTIVITY_CLEAR_TOP 標記,,并且目標Activity在棧中已經(jīng)存在,,則將會把位于該目標activity之上的activity從棧中彈出銷毀。這跟上面把B的Launch mode設(shè)置成singleTask類似,。 FLAG_ACTIVITY_NEW_TASK:例如現(xiàn)在棧1的情況是:A B C,。C通過intent跳轉(zhuǎn)到D,并且這個intent添加了FLAG_ACTIVITY_NEW_TASK 標記,,如果D這個Activity在Manifest.xml中的聲明中添加了Task affinity,,并且和棧1的affinity不同,系統(tǒng)首先會查找有沒有和D的Task affinity相同的task棧存在,,如果有存在,,將D壓入那個棧,如果不存在則會新建一個D的affinity的棧將其壓入,。如果D的Task affinity默認沒有設(shè)置,,或者和棧1的affinity相同,則會把其壓入棧1,,變成:A B C D,,這樣就和不加FLAG_ACTIVITY_NEW_TASK 標記效果是一樣的了。 注意如果試圖從非activity的非正常途徑啟動一個activity,,比如從一個service中啟動一個activity,,則intent比如要添加FLAG_ACTIVITY_NEW_TASK 標記。 FLAG_ACTIVITY_NO_HISTORY:例如現(xiàn)在棧情況為:A B C,。C通過intent跳轉(zhuǎn)到D,,這個intent添加FLAG_ACTIVITY_NO_HISTORY標志,則此時界面顯示D的內(nèi)容,,但是它并不會壓入棧中。如果按返回鍵,,返回到C,,棧的情況還是:A B C,。如果此時D中又跳轉(zhuǎn)到E,棧的情況變?yōu)椋篈 B C E,,此時按返回鍵會回到C,,因為D根本就沒有被壓入棧中。 FLAG_ACTIVITY_SINGLE_TOP:和上面Activity的 Launch mode的singleTop類似,。如果某個intent添加了這個標志,,并且這個intent的目標activity就是棧頂?shù)腶ctivity,那么將不會新建一個實例壓入棧中,。 Activity的主要屬性: allowTaskReparenting:設(shè)置成true時,,和Intent的FLAG_ACTIVITY_NEW_TASK 標記類似。 alwaysRetainTaskStat: 如果用戶長時間將某個task 移入后臺,,則系統(tǒng)會將該task的棧內(nèi)容彈出只剩下棧底的activity,,此時用戶再返回,則只能看到根activity了,。如果棧底的 activity的這個屬性設(shè)置成true,,則將阻止這一行為,從而保留所有的棧內(nèi)容,。 clearTaskOnLaunch:根activity的這個屬性設(shè)置成true時,,和上面的alwaysRetainTaskStat 的屬性為true情況搞好相反。 finishOnTaskLaunch:對于任何activity,,如果它的這個屬性設(shè)置成true,,則當task被放置到后臺,然后重新啟動后,,該activity將不存在了,。 |
|