Android的進(jìn)階學(xué)習(xí)(二)--Activity的啟動模式

好久以前就知道androidActivity有不同的啟動方式,但開始始終沒有弄明白,現(xiàn)在終于梳理清了。

任務(wù)棧

Activity一共有四種不同的啟動模式,分別是standardsingleTopsingleTasksingleInstance,不同的啟動模式,就讓activity存在于內(nèi)存中不同的任務(wù)棧和棧里的位置。這里我們提到了一個任務(wù)棧,其實就是一個后進(jìn)先出的容器,里面存放著Activity

任務(wù)棧.png

在這樣一個任務(wù)棧里面,相當(dāng)于先讓Activity_A進(jìn)棧(直接啟動Activity_A),然后再讓Activity_B進(jìn)棧(從Activity_A以某種模式啟動Activity_B,具體什么方式后面就講),剩下的Activity_CActivity_D也是按照這種方式進(jìn)棧。然后就是出棧了,首先我們明白現(xiàn)在的任務(wù)棧中有4個Activity,接著當(dāng)我們按手機的back鍵的時候,就會按照D,C,B,A出棧,這也就是所說的先進(jìn)后出。當(dāng)然,屏幕顯示的就是棧頂?shù)脑亓恕?/p>

四種啟動模式

一.standard (標(biāo)準(zhǔn)模式)

standard字面意思就是標(biāo)準(zhǔn),沒錯,就是標(biāo)準(zhǔn)模式。當(dāng)Activity以標(biāo)準(zhǔn)模式啟動的時候,就會把該Activity給放入棧頂。沒錯,我們上面的例子就可以用standard模式啟動。

二.singleTop(棧頂復(fù)用模式)

singleTop模式就是講,當(dāng)我們以singleTop啟動Activity的時候,如果這時候的棧頂元素也是我們的需要啟動的Activity,那么這個Activity就不會再次被創(chuàng)建,而是回調(diào)onNewIntent 方法。

棧頂復(fù)用.png

其實這個還是很好理解的,也就和字面意思一樣。好,我們看上面的任務(wù)棧,左邊就是我們開始的樣子(DCBA),然后我們再以singleTop模式去啟動D,然后,發(fā)現(xiàn)任務(wù)棧中還是(DCBA)。這就是棧頂復(fù)用模式。

二.singleTask(棧內(nèi)復(fù)用模式)

singleTask是我覺得這幾種模式中最難理解的,但是慢慢理一下,發(fā)現(xiàn)還是挺簡單的。
singleTask模式啟動的Activity首先就會尋找自己需要的任務(wù)棧,如果沒有,就會創(chuàng)建一個,然后把自己給放進(jìn)棧里面。要是有發(fā)現(xiàn)自己需要的任務(wù)棧,就會看里面有沒有這個Activity的實例,沒有的話就在棧頂加入新創(chuàng)的實例,要是有的話就會彈出該實例上面的所有元素,從而把所需求的實例給推到棧頂。
這樣一說,肯定都還是模模糊糊的,不用怕,我們慢慢理。首先,這里我們提出了一個新的術(shù)語,"Activity需要的任務(wù)棧"。這里我們需要明白,當(dāng)我們沒有為Activity給指定任務(wù)棧的話,那它默認(rèn)的就是我們項目的包名。當(dāng)然,我們可以為其指定一個任務(wù)棧。

<activity
 android:name=".Activity_C"       
android:label="@string/title_activity_activity__c"    
android:taskAffinity="com.mathias.www" 
android:theme="@style/AppTheme.NoActionBar" />

Activity標(biāo)簽中,通過taskAffinity(任務(wù)相關(guān)性)給指定的字符串(字符串中必須包含分割符” . “),這樣當(dāng)我們以singleTask啟動該Activity的時候,就會新建一個任務(wù)棧。但是一般來說我們的Activity都是以默認(rèn)的taskAffinity啟動的。

相同的任務(wù)棧
棧內(nèi)復(fù)用.png

就如上圖一樣,起初我們的任務(wù)棧中有DCBA四個元素,接著,我們以singleTask模式啟動B,那么B就不會被重新創(chuàng)建,而是回調(diào)onNewIntent方法,并且,它還會清掉它上面的元素DC(clearTop效果),這時候你按back鍵的話就是返回到A

不同的任務(wù)棧
棧內(nèi)復(fù)用 (1).png

圖中,我們起初的默認(rèn)任務(wù)棧中有BA兩個元素,然后我們以singleTask(不同的任務(wù)棧,即改變了taskAffinity)啟動C,那么C就會被放到另一個任務(wù)棧中,同時,由于C在前臺,所以C屬于的任務(wù)棧也會被變成我們的前臺任務(wù)棧。
當(dāng)然,有些人可能會說,C不在默認(rèn)的任務(wù)棧中了,但是我們按back鍵還是會回到B呀?對,當(dāng)然會回到B。當(dāng)前臺任務(wù)棧返回的是時候棧里已經(jīng)沒有了元素了,所以就會返回到后臺任務(wù)棧了。
或許你又會說,那這樣啟動Activity有什么作用嗎?好吧,當(dāng)我們在同一個應(yīng)用以不同的任務(wù)棧啟動的時候,好像這個作用并不大(怪我自己還沒找到),但是在一個應(yīng)用代開另一個應(yīng)用的時候就起作用了,當(dāng)一個應(yīng)用A打開了另一個應(yīng)用B的Acctvity后,再返回Home,打開應(yīng)用B,就發(fā)現(xiàn)B沒有在主界面,而是開始A打開的界面,當(dāng)然這里還需要一個Activity的屬性支持 android:allowTaskReparenting="true"

singleInstance(單實例模式)

所謂的singleInstance模式,首先,它具備上一個singleTask的所有屬性,其次,它只能獨自的存在于一個單獨的任務(wù)棧。簡單點就是說,當(dāng)以singleInstance啟動Activity的時候,會為它創(chuàng)建一個新的任務(wù)棧,而且這個任務(wù)棧只會有它一個Activity,后續(xù)的請求也都不會再重新創(chuàng)建它了,所以叫做單例

單實例.png

好吧,我們還是簡單的分析一下(搞什么,圖和上面的一樣):假設(shè)我們當(dāng)前任務(wù)棧中有BA,接著我們以singleInstance模式啟動C,那么C就會在一個獨立的任務(wù)棧中了,然后我們的請求可能會讓前臺任務(wù)棧又變成了默認(rèn)的(BA),這時候,我們再啟動C,就不會創(chuàng)建C,而是直接把C這個任務(wù)棧變成前臺任務(wù)棧,顯示C
也許你看過上面的分析又會有疑問了:明明上面的操作用singleTask就能完成,為什么還要用singleInstance?

解析.png

的確,上面的操作換成singleTask也是可以完成的,但是看我們這圖里面的情況,BA為默認(rèn)的任務(wù)棧,C為新建的。這時候,我們啟動一個和C任務(wù)棧相同的D,那么這里就會變成DC

解析 (1).png

然后,我們一系列的操作 ,又讓前臺任務(wù)棧變成了BA,我們這時候啟動C,那么由于開始說的clearTop屬性就會把D給清理出去了。再創(chuàng)建D的時候就會重建了,然而,如果使用的是singleInsatnce的話就不會出現(xiàn)這種情況了,因為singleInstance中只能有一個Activity

設(shè)置啟動模式

說了這么多,才發(fā)現(xiàn)還沒有講如何設(shè)置......
好吧,設(shè)置Activity啟動模式有兩種方法,一種就是在AndroidManifest.xmlActivitylaunchMode

<activity  
android:name=".Activity_B" 
android:launchMode="singleInstance"    
android:allowTaskReparenting="true"    
android:label="@string/title_activity_activity__b"    
android:theme="@style/AppTheme.NoActionBar" />

另一種就是在代碼中設(shè)置標(biāo)志符了:

Intent intent = new Intent(Activity_A.this,Activity_B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

這兩種方式都可以設(shè)置,但是代碼設(shè)置的優(yōu)先級肯定是比在xml中高的(在代碼中先解析xml,再設(shè)置的)。

最后

還有,這些是我參考《Android開發(fā)藝術(shù)探索》的,對,就是任大大的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,247評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,520評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,362評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,805評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,541評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,896評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,062評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,608評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,356評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,555評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,769評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,175評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,489評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,289評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,516評論 2 379

推薦閱讀更多精彩內(nèi)容