當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]做項(xiàng)目到現(xiàn)在都一直沒有理解LaunchMode有什么用,或許根本就沒真正花心思去看,所以今天把這部分整理下?! ≡O(shè)置Activity的LaunchMode屬性可以決定這個(gè)Activity是和當(dāng)前Tas

做項(xiàng)目到現(xiàn)在都一直沒有理解LaunchMode有什么用,或許根本就沒真正花心思去看,所以今天把這部分整理下。

  設(shè)置Activity的LaunchMode屬性可以決定這個(gè)Activity是和當(dāng)前Task保持關(guān)聯(lián),還是說每次運(yùn)行這個(gè)Activity是新建一個(gè)實(shí)例,還是保持單例。

  Task和Back Stack簡(jiǎn)介

  task是一組Activities的集合,一組Activities被Stack(back stack)所管理。

  在一個(gè)應(yīng)用中,有3個(gè)activities,分別是activity1,activity2,activity3,首先activity1被start,此時(shí),如果應(yīng)用沒有創(chuàng)建task則創(chuàng)建,并把a(bǔ)ctivity1壓入棧頂,activity1觸發(fā)onCreate->onStart->onResume。

  

  接著activity1轉(zhuǎn)向到activity2時(shí),activity1先觸發(fā)onPause,activity2觸發(fā)onCreate->onStart->onResume,然后activity1觸發(fā)onPause->onStop,activity2壓入棧頂。

  

  以此類推,activity2轉(zhuǎn)向activity3也是一樣的步驟。那么當(dāng)前棧頂是activity3。

  

  當(dāng)我們按下手機(jī)上的返回鍵時(shí),棧頂?shù)腶ctivity3觸發(fā)onPause,activity2需要從狀態(tài)stop到pause,所以觸發(fā)了onPause->onStart->onResume,activity3觸發(fā)onStop->onDestory,因?yàn)閍ctivity3從棧頂彈出,所以觸發(fā)onDestory,此時(shí),activity2在棧頂。

  

  如果繼續(xù)按返回鍵,當(dāng)前棧頂?shù)腶ctivity彈出并被destory,直到home界面。當(dāng)所有的activity都彈出了,這個(gè)task也就消亡了。

  當(dāng)開始一個(gè)新的task時(shí),前一個(gè)task被設(shè)置為后臺(tái),在后臺(tái),所有的activity都處理stop狀態(tài),但是back stack保留了所有后臺(tái)activity的狀態(tài)信息,只是丟失了焦點(diǎn)。

  反復(fù)的在兩個(gè)activity之間切換,activity會(huì)產(chǎn)生多個(gè)獨(dú)立的實(shí)例。

  

  查閱有關(guān)Activity生命周期更多說明。

  兩種方式設(shè)置LaunchMode屬性

  1.  在 manifest文件中設(shè)置

  2.  使用Intent flags設(shè)置

Intent?intent?=?new?Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(ActivityA.this,?ActivityB.class);
startActivity(intent);

  四種LaunchMode說明

  standard

   不做任何設(shè)置,默認(rèn)模式就是standard,activity在每次start時(shí),都會(huì)有一個(gè)新的實(shí)例被task管理。下面看下代碼實(shí)例。

//ActivityA.java
Intent?intent?=?new?Intent();
intent.setClass(ActivityA.this,?ActivityB.class);
startActivity(intent);

//ActivityB.java
Intent?intent?=?new?Intent();
intent.setClass(ActivityB.this,?ActivityA.class);
startActivity(intent);

?

 操作1:在ActivityA(藍(lán))和ActivityB(綠)之間重復(fù)切換,按返回鍵推到home界面。

  可以發(fā)現(xiàn)(藍(lán)色86和綠色79的taskID)ActivityA和ActivityB都在同一個(gè)task,并且每次resume的實(shí)例都是不一樣的。這說明在一個(gè)activity可以有多個(gè)實(shí)例在同一個(gè)task中。

  在按返回按鍵時(shí),將依次彈出stack。

??singleTop

  和standard一樣,可以多次實(shí)例,但,如果處于當(dāng)前棧頂并且接受到一個(gè)與當(dāng)前activity一樣類型的intent,那么不會(huì)創(chuàng)建一個(gè)新實(shí)例,而是觸發(fā)onNewIntent()事件。

//ActivityA.java
Intent?intent?=?new?Intent();
intent.setClass(ActivityA.this,?ActivityA.class);
startActivity(intent);

@Override
protected?void?onNewIntent(Intent?intent)?{
????logger.d("onNewIntent?"?+?this.hashCode()?+?"?taskID?"
????????????????+?this.getTaskId());
????super.onNewIntent(intent);
}

操作1:點(diǎn)擊ActivityA上的按鈕

  發(fā)現(xiàn)當(dāng)點(diǎn)擊按鈕是ActivityA->onPause->onNewIntent->onResume,沒有新建新的實(shí)例(藍(lán)62)。

  這個(gè)模式在這個(gè)場(chǎng)景下比較有用,比如:如果有一個(gè)其他的應(yīng)用想啟動(dòng)你的Activity(launch mode為singleTop),而你當(dāng)前的Activity正好在棧頂,那么就會(huì)調(diào)用到onNewIntent方法。原文貼上:If an instance of the activity already exists at the top of the current task, the system routes the intent to that instance through a call to its?onNewIntent()?method。

? singleTask

  系統(tǒng)會(huì)創(chuàng)建一個(gè)新task(如果沒有啟動(dòng)應(yīng)用)和一個(gè)activity新實(shí)例在新task根部,然后,如果activity實(shí)例已經(jīng)存在單獨(dú)的task中,系統(tǒng)會(huì)調(diào)用已經(jīng)存在activity的?onNewIntent()方法,而不是存在新實(shí)例,僅有一個(gè)activity實(shí)例同時(shí)存在。運(yùn)用實(shí)例:瀏覽器主界面。不管跳轉(zhuǎn)多少頁(yè)面,主界面只啟動(dòng)一次,其余都走onNewIntent,并清空主界面上的其他頁(yè)面。

?操作1:ActivityA->ActivityB->ActivityC->ActivityA->ActivityB->ActivityC

  

?  可以看到,當(dāng)再次進(jìn)入ActivityB時(shí),沒有onCreate,而是onNewIntent(綠55)。

   這里我們也可以發(fā)現(xiàn)一個(gè)現(xiàn)象,當(dāng)在調(diào)用到ActivityB的onNewIntent時(shí),之前的ActivityA和ActivityC都調(diào)用了onDestory。也就是說,系統(tǒng)發(fā)現(xiàn)棧中存在ActivityB的實(shí)例時(shí),ActivityA和ActivityB都彈棧了。

   列出Log日志(這里設(shè)ActivityA的LaunchMode為singleTask),ActivityB和ActivityC都在onNewIntent前后調(diào)用了onDestory。

  

  singleInstance

    和singleTask相似,除了系統(tǒng)不會(huì)讓其他的activities運(yùn)行在所有持有的task實(shí)例中,這個(gè)activity是獨(dú)立的,并且task中的成員只有它,任何其他activities運(yùn)行這個(gè)activity都將打開一個(gè)獨(dú)立的task。實(shí)例運(yùn)用:適合與程序分離的頁(yè)面,如鬧鈴提醒。

 操作1:ActivityA->ActivityB->ActivityA

  

?

  可以發(fā)現(xiàn),兩個(gè)Activity是在不同的Task中,其次,當(dāng)調(diào)用到onNewIntent時(shí),ActivityB沒有被Destory,互不干涉。

  操作2:ActivityA->ActivityB->ActivityC,按返回鍵

  

?

  圖解:

  

  剛進(jìn)入應(yīng)用,創(chuàng)建TaskA,ActivityA為棧頂,從ActivityA到ActivityB,ActivityB進(jìn)入TaskB(如果再次進(jìn)入ActivityB,則不創(chuàng)建Task,調(diào)用onNewIntent),此時(shí)TaskB中的ActivityB為棧頂,從ActitivyB到ActivityC,ActivityC為棧頂。

  一直按返回鍵,先從TaskA中依次將Activity彈出,然后再?gòu)腡askB中將ActiviyB彈出。ActiviyC->ActivityA->ActivityB。

  這里分析一個(gè)問題,瀏覽器的LaunchMode為singleTask,所以如果當(dāng)你點(diǎn)擊一個(gè)連接下載文件時(shí)(由一個(gè)activity來(lái)處理下載,launchmode為standard),如果再次進(jìn)入瀏覽器,那么下載頁(yè)面就被Destory了,那么這里我們可以把下載頁(yè)面LaunchMode設(shè)置為singleInstance可以解決這個(gè)問題。

  Affinity定義

  Affinity更像是表明了activity屬于哪個(gè)task,默認(rèn)情況下,應(yīng)用所有的activities都有相同的affinity,所以都是在相同的task中。然后你可以編輯默認(rèn)的affinity。Activities定義在不同的應(yīng)用可以共享一個(gè)affinity,或者activities定義在相同的應(yīng)用中可以被不同的affinities所關(guān)聯(lián)。

  你可以編輯在activity的taskAffinity屬性。

  ?先看看兩種不同的情況下affinity的表現(xiàn):

當(dāng)運(yùn)行一個(gè)activity包含了FLAG_ACTIVITY_NEW_TASK標(biāo)記

//ActivityA.java
Intent?intent?=?new?Intent();????
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(ActivityA.this,?ActivityB.class);
startActivity(intent);

操作1:不同的affinity值,ActivityA->ActivityB

如果已經(jīng)存在相同affinity,那么新activity運(yùn)行在這個(gè)task中,否則,系統(tǒng)創(chuàng)建新task。

操作2:相同的affinity值,ActivityA->ActivityB


可以看出ActivityA和ActivityB都運(yùn)行在同一個(gè)task中。

?

當(dāng)Activity的allowTaskReparenting的屬性設(shè)為'true'

  使用來(lái)表示是否允許activity重新附屬其他Task,還是舉例說明吧。

  有兩個(gè)應(yīng)用,Demo1和Demo2,Demo1中有2個(gè)Activity(ActivityA,ActivityC),ActivityA可以轉(zhuǎn)向到ActivityC,Demo2中有一個(gè)Activity(ActivityB),也可以轉(zhuǎn)向到ActivityC。

  操作1:設(shè)置ActivityC的allowTaskReparenting屬性為true。

      運(yùn)行Demo2,轉(zhuǎn)向到ActivityC,在ActivityC中打印信息,返回到HOME界面,運(yùn)行Demo1。

//Demo1?
//ActivityA.java
Intent?intent?=?new?Intent();
intent.setClass(ActivityA.this,?ActivityC.class);
startActivity(intent);

//ActivityC.java
tv.setText(ActivityC.this.toString());

//Demo2
//ActivityB.java
Intent?intent?=?new?Intent();
intent.setClassName("com.android.demo","com.android.demo.activity.ActivityC");
ActivityB.this.startActivity(intent);
//Demo1

//Demo2

?運(yùn)行結(jié)果:(黃色Demo1,綠色Demo2)

  

?  ?ActivityB轉(zhuǎn)向到ActivityC,此時(shí)ActivityC就關(guān)聯(lián)到Demo2的Task中,TaskID都為231。在運(yùn)行Demo1時(shí),看到是ActivityC而不是ActivityA。當(dāng)再次進(jìn)入Demo2時(shí)就看不到ActivityC了。

  操作2:將ActivityC的taskAffinity設(shè)置為"com.android.demo.activityc"。

      運(yùn)行Demo2,轉(zhuǎn)向到ActivityC,在ActivityC中打印信息,返回到HOME界面,運(yùn)行Demo1。

//Demo1

?運(yùn)行結(jié)果:

  

?  從結(jié)果中可以看出,Demo1和Demo2都擁有ActivityC,也就是說有2個(gè)Task里存在ActivityC,分別被Demo1和Demo2所使用。

  操作3:將ActivityC和ActivityB的taskAffinity都設(shè)為"com.android.demo.activityc"。

      運(yùn)行Demo2,轉(zhuǎn)向到ActivityC,在ActivityC中打印信息,返回到HOME界面,運(yùn)行Demo1。

//Demo2            //Demo1        

  運(yùn)行結(jié)果:

  

?  和操作1相反,再進(jìn)入Demo2時(shí)看到是ActivityC,進(jìn)入Demo1都是看到ActivityA。

?

  寫到最后越來(lái)越崩潰了,如果有什么地方寫的不對(duì)或不清楚請(qǐng)指明。

  轉(zhuǎn)帖請(qǐng)說明原文出處:http://www.cnblogs.com/SteveMing/archive/2012/04/24/2459575.html?

另一篇 圖文并茂?http://www.androidchina.net/3173.html?

兩種設(shè)置方式:

1) XML

2)在java代碼中設(shè)置intent.setFlags()


Intent?intent?=?new?Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(this,ActivitySub.ckass);
startActivity(intent);
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉