最近2018中文字幕在日韩欧美国产成人片_国产日韩精品一区二区在线_在线观看成年美女黄网色视频_国产精品一区三区五区_国产精彩刺激乱对白_看黄色黄大色黄片免费_人人超碰自拍cao_国产高清av在线_亚洲精品电影av_日韩美女尤物视频网站

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
android啟動(dòng)模式,android 四種啟動(dòng)模式

Android中的Activity詳解--啟動(dòng)模式與任務(wù)棧

目錄

公司主營業(yè)務(wù):網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出薩爾圖免費(fèi)做網(wǎng)站回饋大家。

activity的簡(jiǎn)單介紹就不寫了,作為最常用的四大組件之一,肯定都很熟悉其基本用法了。

首先,是都很熟悉的一張圖,即官方介紹的Activity生命周期圖.

情景:打開某個(gè)應(yīng)用的的FirstActivity調(diào)用方法如下:

由于之前已經(jīng)很熟悉了,這里就簡(jiǎn)單貼一些圖。

按下返回鍵:

重新打開并按下home鍵:

再重新打開:

在其中打開一個(gè)DialogActivity(SecondActivity)

按下返回:

修改SecondAcitvity為普通Activity,依舊是上述操作:

這里強(qiáng)調(diào)一下 onSaveInstanceState(Bundle outState) 方法的調(diào)用時(shí)機(jī):

當(dāng)Activity有可能被系統(tǒng)殺掉時(shí)調(diào)用,注意,一定是被系統(tǒng)殺掉,自己調(diào)用finish是不行的。

測(cè)試如下:FirstActivity啟動(dòng)SecondActivity:

一個(gè)App會(huì)包含很多個(gè)Activity,多個(gè)Activity之間通過intent進(jìn)行跳轉(zhuǎn),那么原始的Activity就是使用棧這個(gè)數(shù)據(jù)結(jié)構(gòu)來保存的。

Task

A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the back stack ), in the order in which each activity is opened.

即若干個(gè)Activity的集合的棧表示一個(gè)Task。

當(dāng)App啟動(dòng)時(shí)如果不存在當(dāng)前App的任務(wù)棧就會(huì)自動(dòng)創(chuàng)建一個(gè),默認(rèn)情況下一個(gè)App中的所有Activity都是放在一個(gè)Task中的,但是如果指定了特殊的啟動(dòng)模式,那么就會(huì)出現(xiàn)同一個(gè)App的Activity出現(xiàn)在不同的任務(wù)棧中的情況,即會(huì)有任務(wù)棧中包含來自于不同App的Activity。

標(biāo)準(zhǔn)模式,在不指定啟動(dòng)模式的情況下都是以此種方式啟動(dòng)的。每次啟動(dòng)都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例,覆蓋在原有的Activity上,原有的Activity入棧。

測(cè)試如下:在FirstActivity中啟動(dòng)FirstActivity:

當(dāng)只有一個(gè)FirstActivity時(shí)堆棧情況:

此種模式下,Activity在啟動(dòng)時(shí)會(huì)進(jìn)行判斷,如果當(dāng)前的App的棧頂?shù)腁ctivity即正在活動(dòng)的Activity就是將要啟動(dòng)的Activity,那么就不會(huì)創(chuàng)建新的實(shí)例,直接使用棧頂?shù)膶?shí)例。

測(cè)試,設(shè)置FirstActivity為此啟動(dòng)模式,多次點(diǎn)擊FirstActivity中的啟動(dòng)FirstActivity的按鈕查看堆棧情況:

(其實(shí)點(diǎn)擊按鈕沒有啟動(dòng)新Activity的動(dòng)畫就可以看出并沒有啟動(dòng)新Activity)

大意就是:

對(duì)于使用singleTop啟動(dòng)或Intent.FLAG_ACTIVITY_SINGLE_TOP啟動(dòng)的Activity,當(dāng)該Activity被重復(fù)啟動(dòng)(注意一定是re-launched,第一次啟動(dòng)時(shí)不會(huì)調(diào)用)時(shí)就會(huì)調(diào)用此方法。

且調(diào)用此方法之前會(huì)先暫停Activity也就是先調(diào)用onPause方法。

而且,即使是在新的調(diào)用產(chǎn)生后此方法被調(diào)用,但是通過getIntent方法獲取到的依舊是以前的Intent,可以通過setIntent方法設(shè)置新的Intent。

方法參數(shù)就是新傳遞的Intent.

1.如果是同一個(gè)App中啟動(dòng)某個(gè)設(shè)置了此模式的Activity的話,如果棧中已經(jīng)存在該Activity的實(shí)例,那么就會(huì)將該Activity上面的Activity清空,并將此實(shí)例放在棧頂。

測(cè)試:SecondActivity啟動(dòng)模式設(shè)為singleTask,啟動(dòng)三個(gè)Activity:

這個(gè)模式就很好記,以此模式啟動(dòng)的Activity會(huì)存放在一個(gè)單獨(dú)的任務(wù)棧中,且只會(huì)有一個(gè)實(shí)例。

測(cè)試:SecondActivity啟動(dòng)模式設(shè)為singleInstance

結(jié)果:

顯然,啟動(dòng)了兩次ThirdActivity任務(wù)棧中就有兩個(gè)實(shí)例,而SecondActivity在另外一個(gè)任務(wù)棧中,且只有一個(gè)。

在使用Intent啟動(dòng)一個(gè)Activity時(shí)可以設(shè)置啟動(dòng)該Activity的啟動(dòng)模式:

這個(gè)屬性有很多,大致列出幾個(gè):

每個(gè)啟動(dòng)的Activity都在一個(gè)新的任務(wù)棧中

singleTop

singleTask

用此種方式啟動(dòng)的Activity,在它啟動(dòng)了其他Activity后,會(huì)自動(dòng)finish.

官方文檔介紹如下:

這樣看來的話,通俗易懂的講,就是給每一個(gè)任務(wù)棧起個(gè)名,給每個(gè)Activity也起個(gè)名,在Activity以singleTask模式啟動(dòng)時(shí),就檢查有沒有跟此Activity的名相同的任務(wù)棧,有的話就將其加入其中。沒有的話就按照這個(gè)Activity的名創(chuàng)建一個(gè)任務(wù)棧。

測(cè)試:在App1中設(shè)置SecondActivity的taskAffinity為“gsq.test”,App2中的ActivityX的taskAffinity也設(shè)為“gsq.test”

任務(wù)棧信息如下:

結(jié)果很顯然了。

測(cè)試:在上述基礎(chǔ)上,在ActivityX中進(jìn)行跳轉(zhuǎn)到ActivityY,ActivityY不指定啟動(dòng)模式和taskAffinity。結(jié)果如下:

這樣就沒問題了,ActivityY在一個(gè)新的任務(wù)棧中,名稱為包名。

這時(shí)從ActivityY跳轉(zhuǎn)到SecondActivity,那應(yīng)該是gsq.test任務(wù)棧只有SecondActivity,ActivityX已經(jīng)沒有了。因?yàn)槠鋯?dòng)模式是singleTask,在啟動(dòng)它時(shí)發(fā)現(xiàn)已經(jīng)有一個(gè)實(shí)例存在,就把它所在的任務(wù)棧上面的Activity都清空了并將其置于棧頂。

還有一點(diǎn)需要提一下,在上面,F(xiàn)irstActivity是App1的lunch Activity,但是由于SecondActivity并沒有指定MAIN和LAUNCHER過濾器,故在FirstActivity跳轉(zhuǎn)到SecondActivity時(shí),按下home鍵,再點(diǎn)開App1,回到的是FirstActivity。

大致就先寫這么多吧,好像有點(diǎn)長(zhǎng),廢話有點(diǎn)多,估計(jì)也有錯(cuò)別字,不要太在意~~~

Android Activity啟動(dòng)模式與狀態(tài)保存及恢復(fù)詳解

Activity是 Android組件 中最基本也是最為常見用的四大組件(Activity,Service服務(wù),Content Provider內(nèi)容提供者,BroadcastReceiver廣播接收器)之一 。

Activity是一個(gè)應(yīng)用程序 組件 ,提供一個(gè) 屏幕 ,用戶可以用來交互為了完成某項(xiàng)任務(wù)。

Activity中所有操作都與用戶密切相關(guān),是一個(gè)負(fù)責(zé)與 用戶交互 的組件,可以通過setContentView(View)來 顯示指定控件 。

在一個(gè)android應(yīng)用中,一個(gè)Activity通常就是一個(gè)單獨(dú)的屏幕,它上面可以顯示一些控件也可以監(jiān)聽并處理用戶的事件做出響應(yīng)。Activity之間通過Intent進(jìn)行通信。

關(guān)于Activity啟動(dòng)流程請(qǐng)參考之前的文章 Android activity啟動(dòng)流程分析

activity有四種啟動(dòng)模式,分別為standard,singleTop,singleTask,singleInstance。如果要使用這四種啟動(dòng)模式,必須在manifest文件中activity標(biāo)簽中的launchMode屬性中配置。

標(biāo)準(zhǔn)的默認(rèn)啟動(dòng)模式,這種模式下activity可以被多次實(shí)例化,即在一個(gè)task中可以存在多個(gè)activity,每一個(gè)activity會(huì)處理一個(gè)intent對(duì)象,(在A中再次啟動(dòng)A,會(huì)存在后面的A在前面的A上面,當(dāng)前task會(huì)存在兩個(gè)activity的實(shí)例對(duì)象)

如果一個(gè)singleTop模式啟動(dòng)的activity實(shí)例已經(jīng)存在于棧頂,那么再次啟動(dòng)這個(gè)activity的時(shí)候,不會(huì)重新創(chuàng)建實(shí)例,而是重用位于棧頂?shù)哪莻€(gè)實(shí)例,并且會(huì)調(diào)用實(shí)例的onNewIntent()方法將Intent對(duì)象傳遞到這個(gè)實(shí)例中,如果實(shí)例不位于棧頂,會(huì)創(chuàng)建新的實(shí)例。

啟動(dòng)模式設(shè)置為singleTask,framework在啟動(dòng)該activity時(shí)只會(huì)把它標(biāo)示為可在一個(gè)新任務(wù)中啟動(dòng),至于是否在一個(gè)新任務(wù)中啟動(dòng),還要受其他條件的限制,即taskAffinity屬性。

taskAffinity :默認(rèn)情況下,一個(gè)應(yīng)用中的所有activity具有相同的taskAffinity,即應(yīng)用程序的包名。我們可以通過設(shè)置不同的taskAffinity屬性給應(yīng)用中的activity分組,也可以把不同的應(yīng)用中的activity的taskAffinity設(shè)置成相同的值,當(dāng)兩個(gè)不同應(yīng)用中的activity設(shè)置成相同的taskAffinity時(shí),則兩個(gè)activity會(huì)屬于同一個(gè)TaskRecord。

在啟動(dòng)一個(gè)singleTask的Activity實(shí)例時(shí),如果系統(tǒng)中已經(jīng)存在這樣一個(gè)實(shí)例,就會(huì)將這個(gè)實(shí)例調(diào)度到任務(wù)棧的棧頂,并清除它當(dāng)前所在任務(wù)中位于它上面的所有的activity;如果這個(gè)已存在的任務(wù)中不存在一個(gè)要啟動(dòng)的Activity的實(shí)例,則在這個(gè)任務(wù)的頂端啟動(dòng)一個(gè)實(shí)例;若這個(gè)任務(wù)不存在,則會(huì)啟動(dòng)一個(gè)新的任務(wù),在這個(gè)新的任務(wù)中啟動(dòng)這個(gè)singleTask模式的Activity的一個(gè)實(shí)例。

以singleInstance模式啟動(dòng)的Activity具有全局唯一性,即整個(gè)系統(tǒng)中只會(huì)存在一個(gè)這樣的實(shí)例,如果在啟動(dòng)這樣的Activiyt時(shí),已經(jīng)存在了一個(gè)實(shí)例,那么會(huì)把它所在的任務(wù)調(diào)度到前臺(tái),重用這個(gè)實(shí)例。

以singleInstance模式啟動(dòng)的Activity具有獨(dú)占性,即它會(huì)獨(dú)自占用一個(gè)任務(wù),被他開啟的任何activity都會(huì)運(yùn)行在其他任務(wù)中(官方文檔上的描述為,singleInstance模式的Activity不允許其他Activity和它共存在一個(gè)任務(wù)中)。

被singleInstance模式的Activity開啟的其他activity,能夠開啟一個(gè)新任務(wù),但不一定開啟新的任務(wù),也可能在已有的一個(gè)任務(wù)中開啟,受條件的限制,這個(gè)條件是:當(dāng)前系統(tǒng)中是不是已經(jīng)有了一個(gè)activity B的taskAffinity屬性指定的任務(wù)。

涉及到Activity啟動(dòng),就不得不說一下Activity的管理,Activity是以什么方式及被什么類來進(jìn)行管理的,涉及的類主要如下:

歷史棧中的一個(gè)條目,代表一個(gè)activity。ActivityRecord中的成員變量task表示其所在的TaskRecord,ActivityRecord與TaskRecord建立了聯(lián)系。

內(nèi)部維護(hù)一個(gè) ArrayListActivityRecord 用來保存ActivityRecord,TaskRecord中的mStack表示其所在的ActivityStack,TaskRecord與ActivityStack建立了聯(lián)系。

內(nèi)部維護(hù)了一個(gè) ArrayListTaskRecord ,用來管理TaskRecord,ActivityStack中持有ActivityStackSupervisor對(duì)象,由ActivityStackSupervisor創(chuàng)建。

負(fù)責(zé)所有ActivityStack的管理。內(nèi)部管理了mHomeStack、mFocusedStack和mLastFocusedStack三個(gè)Activity棧。其中,mHomeStack管理的是Launcher相關(guān)的Activity棧;mFocusedStack管理的是當(dāng)前顯示在前臺(tái)Activity的Activity棧;mLastFocusedStack管理的是上一次顯示在前臺(tái)Activity的Activity棧。

ActivityThread 運(yùn)行在UI線程(主線程),App的真正入口。

用來實(shí)現(xiàn)AMS和ActivityThread之間的交互。

負(fù)責(zé)調(diào)用Activity和Application生命周期。

當(dāng)一個(gè)Activity未被主動(dòng)關(guān)閉,即“被動(dòng)關(guān)閉”時(shí),可能需要系統(tǒng)給用戶提供保持一些狀態(tài)的入口。

前面說的入口就是:Activity提供了onSaveInstanceState()方法,該方法是Activity在關(guān)閉前保存狀態(tài)的核心方法。

前面提到“被動(dòng)關(guān)閉”,如果是主動(dòng)關(guān)閉那么就不會(huì)調(diào)用,比如:按back鍵、調(diào)用finish()等,那么"被動(dòng)關(guān)閉"的場(chǎng)景有哪些呢?下面給列舉一下:

肯定在調(diào)用onStop()前被調(diào)用,但不保證在onPause()前 / 后,一般是在onPause()后調(diào)用。

當(dāng)需要保持狀態(tài)時(shí),在onSaveInstanceState()內(nèi)執(zhí)行以下邏輯:

當(dāng)需要恢復(fù)時(shí),在onCreate()內(nèi)部執(zhí)行以下邏輯:

布局每個(gè)View默認(rèn)實(shí)現(xiàn):onSaveInstanceState(),即UI的任何改變都會(huì)自動(dòng)的存儲(chǔ)和在activity重新創(chuàng)建的時(shí)候自動(dòng)的恢復(fù)(只有在為該UI提供了唯一ID后才起作用);

若需復(fù)寫該方法從而存儲(chǔ)額外的狀態(tài)信息時(shí),應(yīng)先調(diào)用父類的onSaveInstanceState()(因?yàn)槟J(rèn)的onSaveInstanceState()幫助UI存儲(chǔ)它的狀態(tài));

只使用該方法記錄Activity的瞬間狀態(tài)(UI的狀態(tài)),而不是去存儲(chǔ)持久化數(shù)據(jù),因?yàn)閛nSaveInstanceState()調(diào)用時(shí)機(jī)不確定性;可使用 onPause()[一定會(huì)執(zhí)行]存儲(chǔ)持久化數(shù)據(jù);

Activity提供了onRestoreInstanceState()方法,該方法是Activity在重新創(chuàng)建后恢復(fù)之前保存狀態(tài)的核心方法。

若被動(dòng)關(guān)閉了Activity,即調(diào)用了onSaveInstanceState(),那么下次啟動(dòng)時(shí)會(huì)調(diào)用onRestoreInstanceState()。

onCreate()---onStart()---onRestoreInstanceState()---onResume()

注意: onSaveInstanceState()、onRestoreInstanceState()不一定 成對(duì)被調(diào)用

如:當(dāng)正在顯示Activity A時(shí),用戶按下HOME鍵回到主界面,然后用戶緊接著又返回到Activity A,此時(shí)Activity A一般不會(huì)因?yàn)閮?nèi)存的原因被系統(tǒng)銷毀,故Activity A的onRestoreInstanceState()不會(huì)被執(zhí)行;

針對(duì)以上情況,onSaveInstanceState保持的參數(shù)可以選擇在onCreate()內(nèi)部進(jìn)行解析使用,因?yàn)閛nSaveInstanceState的bundle參數(shù)會(huì)傳遞到onCreate方法中,可選擇在onCreate()中做數(shù)據(jù)還原。

至此:Activity的啟動(dòng)模式及Activity的狀態(tài)保持及恢復(fù)介紹完畢。

Android的啟動(dòng)模式:singleTask與singleTop的使用

singleTop 與 singleTask 是 Activity 最常用的兩種啟動(dòng)模式。本文主要講解兩者之間的區(qū)別與使用場(chǎng)景。

個(gè)人博客: 李益的小站

Activity 共有四種啟動(dòng)模式,我們先簡(jiǎn)單回顧一下,如想要詳細(xì)了解的,可自行網(wǎng)上查詢(相關(guān)文章很多哦,本文就不再詳細(xì)贅述)了。

使用 singleTop 模式的 Activity 在棧頂時(shí)只會(huì)在 Task 中存在一個(gè)實(shí)例,所以可以在以下場(chǎng)景中使用:

總之, singleTop 比較適用于 ChildActivity (非主架構(gòu)Activity)

所以基于以上特性,比較適合主架構(gòu) Activity (例MainActivity)設(shè)置為 singleTask ,或者一些經(jīng)常使用,但是關(guān)閉和跳轉(zhuǎn)不規(guī)律的 Activity

Android四種啟動(dòng)模式在什么時(shí)候使用?

standard(默認(rèn))

系統(tǒng)默認(rèn)的啟動(dòng)模式。

Android是使用返回棧來管理活動(dòng)的,在standard模式下,每當(dāng)啟動(dòng)一個(gè)新的活動(dòng),它就會(huì)在返回棧中入棧,并處于棧頂?shù)奈恢谩?/p>

對(duì)于使用standard模式的活動(dòng),系統(tǒng)不會(huì)在乎這個(gè)活動(dòng)是否已經(jīng)在返回棧中存在,而是每次啟動(dòng)活動(dòng)都會(huì)創(chuàng)建該活動(dòng)的一個(gè)新的實(shí)例。

singleTop

android:launchMode="singleTop"

當(dāng)活動(dòng)的啟動(dòng)模式指定為singleTop,在啟動(dòng)活動(dòng)時(shí),如果發(fā)現(xiàn)該返回棧的棧頂已經(jīng)是該活動(dòng)時(shí),則認(rèn)為可以直接使用它,不會(huì)在創(chuàng)建新的活動(dòng)實(shí)例

singleTask

當(dāng)活動(dòng)的啟動(dòng)模式指定為singleTask,每次啟動(dòng)該活動(dòng)時(shí),首先會(huì)在返回棧中檢查是否存在該活動(dòng)的實(shí)例,如果發(fā)現(xiàn)已經(jīng)存在就直接使用該實(shí)例,并把這個(gè)活動(dòng)之上的所有活動(dòng)統(tǒng)統(tǒng)出棧,如果沒有發(fā)現(xiàn)就會(huì)創(chuàng)建一個(gè)新的活動(dòng)實(shí)例。

android:launchMode="singleTask"

singleInstance

指定為singleInstance模式的活動(dòng)會(huì)啟用一個(gè)新的返回棧來管理這個(gè)活動(dòng),不管是哪個(gè)應(yīng)用程序來訪問這個(gè)活動(dòng),都共用的同一個(gè)返回棧,解決了共享活動(dòng)實(shí)例的問題

修改SecondActivity的啟動(dòng)模式

android:launchMode="singleInstance"

使用方式:

standard:怎么樣都要?jiǎng)?chuàng)建

singleTop:頂上不是target Activity,new一個(gè)

singleTask:頂上不是target Activity,移除target之上的,把自己變成top。

singleInstance:開辟私有的task,完全獨(dú)立于程序的其他activity的task。

使用場(chǎng)景:

standard:普通activity

singleTop:要展示推送過來的消息

singleTask:程序入口等啟動(dòng)頁面

singleInstance:完全獨(dú)立的,類似鬧鐘的提示

Android: Activity啟動(dòng)模式 FLAG_ACTIVITY_NEW_TASK 詳細(xì)探索

最近遇到了一個(gè)小問題,在我使用了多種Activity啟動(dòng)模式的時(shí)候,重新打開其中的一個(gè)Activity會(huì)啟動(dòng)另一個(gè)我已經(jīng)停止的Activity,從而調(diào)用了一些已經(jīng)失效的方法導(dǎo)致程序崩潰。

由于項(xiàng)目工程復(fù)雜,Activity名稱不夠直觀,我新建了一個(gè)ActivityTaskTest 工程來重現(xiàn)遇到的問題。

ActivityA是工程的主活動(dòng)。因?yàn)橐恍┍匾脑颍?ActivityA的啟動(dòng)模式是SingleInstance的。ActivityA可以啟動(dòng)ActivityB,ActivityB沒有設(shè)置任何啟動(dòng)模式,即默認(rèn)的standard啟動(dòng)模式。在ActivityB中,將會(huì)啟動(dòng)一個(gè)ServiceA。 ServiceA中啟動(dòng)一個(gè)了一個(gè)ActivityC,由于Activity是在非Acitivity環(huán)境下啟動(dòng)的,需要設(shè)置 FLAG_ACTIVITY_NEW_TASK標(biāo)簽(這里就是我們討論的重點(diǎn),稍候會(huì)詳細(xì)分析)。當(dāng)ActivityC完成任務(wù)后會(huì)重新跳轉(zhuǎn)到ActivityA。

最后,見證奇葩的時(shí)刻到了,我們點(diǎn)擊ActivityA的啟動(dòng)ActivityB的button,ActivityC出現(xiàn)在了我們的眼前,而不是ActivityB?。∵@一刻我仿佛劉謙附體,但在我發(fā)現(xiàn)我身邊并沒有董卿之后,我深刻地意識(shí)到了我是一個(gè)工程師,不能搞這些裝神弄鬼的事情。ok,Let's find out what‘s going on with our precious app!

關(guān)于Activity啟動(dòng)模式和Activity Task的內(nèi)容推薦一篇非常好的文章: Android中Activity四種啟動(dòng)模式和taskAffinity屬性詳解 。這篇文章已經(jīng)講得非常詳細(xì)了,這里就不再贅述了,偷個(gè)懶哈哈。

如果你已經(jīng)看了文章,你應(yīng)該已經(jīng)知道問題的所在了,對(duì),就是這個(gè)該死的taskAffinity。簡(jiǎn)單的說,就是我們雖然使用了FLAG_ACTIVITY_NEW_TASK標(biāo)簽去啟動(dòng)了ActivityC,但是因?yàn)槲覀兺私oActivity設(shè)置taskAffinity這個(gè)小婊砸,所以導(dǎo)致ActivityC的taskAffinity值和ActivityB一樣都是默認(rèn)的包名。所以我們啟動(dòng)ActivityC的時(shí)候系統(tǒng)將ActivityC壓入了ActivityB所在的task。我們可以使用adb shell dumpsys activity activities 指令看下一在我們重新從A中啟動(dòng)B之前,Task的情況:

我們可以看到正如我們所想的,ActivityC和ActivityB在一個(gè)Task中,由于ActivityA是singleInstance模式,所以A只能做一輩子單身狗了。那么為什么我們明明啟動(dòng)的是B,怎么會(huì)出現(xiàn)C呢?

我們來先看看Google官方文檔對(duì)于FLAG_ACTIVITY_NEW_TASK是怎么說的:

注意文檔中的內(nèi)容,“如果要啟動(dòng)的 activity 已經(jīng)運(yùn)行于某 task 中,則那個(gè) task 將調(diào)入前臺(tái),最后保存的狀態(tài)也將恢復(fù)”,注意這里是所在task被直接調(diào)入前臺(tái),也就是說B所在的整個(gè)Task將被移入前臺(tái)。這就解釋了為什么我們?nèi)?dòng)B而出現(xiàn)的是C了??雌饋砦覀兒孟翊蠊Ω娉闪耍?,等等,總覺得哪里有點(diǎn)不太對(duì)勁,我們的ActivityB明明沒有設(shè)置啟動(dòng)模式啊,你這個(gè)是FLAG_ACTIVITY_NEW_TASK標(biāo)簽,我沒用啊,我讀書多你可別騙我。

仔細(xì)想想應(yīng)該是ActivityA的singleInstance的鍋。

我們?cè)賮砜纯碐oogle官方文檔對(duì)于singleInstance是怎么說的吧:

看到最后一句,終于可以結(jié)案了。也就是說,當(dāng)一個(gè)被設(shè)置為singleInstance的Activity去啟動(dòng)其他的Activity的時(shí)候,其默認(rèn)是自帶FLAG_ACTIVITY_NEW_TASK標(biāo)簽的。

1、FLAG_ACTIVITY_NEW_TASK標(biāo)簽必須配合taskAffinity屬性使用,如果不設(shè)置taskAffinity屬性值,將不會(huì)生成新task。

2、當(dāng)從啟動(dòng)模式為singleInstance的Acitivity中啟動(dòng)新的Acitivity時(shí),新的Activity自帶FLAG_ACTIVITY_NEW_TASK標(biāo)簽。

心得:官方文檔是個(gè)好東西。


本文題目:android啟動(dòng)模式,android 四種啟動(dòng)模式
文章URL:http://fisionsoft.com.cn/article/dsiopip.html