Activity的四種啟動模式

Activity四種啟動模式

這部分應該是最最基礎的了,但是還是有很多細節需要把握,不只是表面的知識點。

  • 1 Activity的管理是采用任務棧的形式
  • 2 任務棧采用“后進先出”的棧結構
  • 3 每按一次Back鍵,就有一個Activity出棧
image.png
  • 標準模式(standard)
    每啟動一次Activity,就會創建一個新的Activity實例并置于棧頂誰啟動了這個Activity,那么這個Activity就運行在啟動它的那個Activity所在的棧中。也就是說在ActivityA中啟動了ActivityB那么ActivityB就在ActivityA的棧中
image.png
  • 單例模式(singleInstance)
  1. 作為棧內復用模式(singleTask)的加強版
  2. 打開該Activity時,直接創建一個新的任務棧,并創建該Activity實例放入新棧中
  3. 一旦該模式的Activity實例已經存在于某個棧中,任何應用再激活該Activity時都會重用該棧中的實例
  4. 使用場景:多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。使用場景如鬧鈴提醒,將鬧鈴提醒與鬧鈴設置分離。
    四種啟動模式圖解

image.png

四種啟動模式的區別

  • 決定打開的任務棧
    standard、singleTop啟動模式的Activity的目標任務棧,和收到Intent的發送者在同一個任務棧內。
    singleTask啟動模式打開的任務棧由參數TaskAffinity決定。
    singleInstance啟動模式總是新建任務棧,不會被啟動到一個其他任務棧里。
  • 是否允許多個相同的Activity實例
    standard、singleTop啟動模式中,同一個Activity可以被實例化多次,并且存在于不同的任務棧中,且一個任務棧可以包括同一個Activity的多個實例;
    singleTask、singleInstance啟動模式則限制只生成一個實例。
  • 是否允許不同的Activity實例存在于同一個任務棧內
    singleInstance啟動模式獨占一個任務棧,其它Activity實例不能存在于該任務棧里。
    另外三種模式,則可以和其它Activity實例共存于一個任務棧。
  • 是否每次都生成新實例
    standard模式:每次都生成新實例。
    singleTop模式:若啟動的Activity不在棧頂,則生成新實例;
    singleInstance模式:所在棧的唯一Activity實例,只會實例化一次,以后每次都被重用。
    singleTask模式:若啟動的Activity不在棧內,則生成新實例;
    啟動模式的設置
    啟動模式有兩種設置方式:
  • 在AndroidMainifest設置
  • 通過Intent設置標志位
    1.在AndroidMainifest中設置
image.png

2.通過Intent設置標志位

image.png

image.png

二者設置的區別

  • Intent設置方式比Manifest設置方式的優先級要高,即以前者為準
  • 限定范圍不同
    Manifest設置方式無法設定FLAG_ACTIVITY_CLEAR_TOP標識;Intent設置方式無法設置單例模式(singleInstance)
    介紹一下任務棧:
    (1)程序打開時就創建了一個任務棧, 用于存儲當前程序的activity,所有的activity屬于一個任務棧。
    (2)一個任務棧包含了一個activity的集合,去有序的選擇哪一個activity和用戶進行交互:只有在任務棧棧頂的activity才可以跟用戶進行交互。
    (3)任務??梢砸苿拥胶笈_,并且保留了每一個activity的狀態. 并且有序的給用戶列出它們的任務,而且還不丟失它們狀態信息。
    (4)退出應用程序時:當把所有的任務棧中所有的activity清除出棧時,任務棧會被銷毀,程序退出。
    任務棧的缺點:
    (1)每開啟一次頁面都會在任務棧中添加一個Activity,而只有任務棧中的Activity全部清除出棧時,任務棧被銷毀,程序才會退出,這樣就造成了用戶體驗差,需要點擊多次返回才可以把程序退出了。
    (2)每開啟一次頁面都會在任務棧中添加一個Activity還會造成數據冗余,重復數據太多,會導致內存溢出的問題(OOM)。
    為了解決任務棧的缺點,我們引入了啟動模式。
    Standard
    ???默認模式 v,可以不用寫配置。在這個模式下,都會默認創建一個新的實例。因此,在這種模式下,可以有多個相同的實例,也允許多個相同Activity疊加。
    ??若我有一個Activity名為A1, 上面有一個按鈕可跳轉到A1。那么如果我點擊按鈕,便會新啟一個Activity A1疊在剛才的A1之上,再點擊,又會再新啟一個在它之上…….
    ??點back鍵會依照棧順序依次退出。
    singleTop
    ??可以有多個實例,但是不允許多個相同Activity疊加。即,如果Activity在棧頂的時候,啟動相同的Activity,不會創建新的實例,而會調用其onNewIntent方法。
    例如:
    ??若我有兩個Activity名為B1,B2,兩個Activity內容功能完全相同,都有兩個按鈕可以跳到B1或者B2,唯一不同的是B1為standard,B2為singleTop。
    ??若我意圖打開的順序為B1->B2->B2,則實際打開的順序為B1->B2(后一次意圖打開B2,實際只調用了前一個的onNewIntent方法)
    ??若我意圖打開的順序為B1->B2->B1->B2,則實際打開的順序與意圖的一致,為B1->B2->B1->B2。
    singleTask
    ???只有一個實例。在同一個應用程序中啟動的它時候,若Activity不存在,則會在當前task創建一個新的實例,若存在,則會把task中在其之上的其它Activity destory掉并調用它的onNewIntent方法。
    ???如果是在別的應用程序中啟動它,則會新建一個task,并在該task中啟動這個Activity,singleTask允許別的Activity與其在一個task中共存,也就是說,如果我在這個singleTask的實例中再打開新的Activity,這個新的Activity還是會在singleTask的實例的task中。
    例如:
    ???若我的應用程序中有三個Activity,C1,C2,C3,三個Activity可互相啟動,其中C2為singleTask模式,那么,無論我在這個程序中如何點擊啟動,如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在多個實例,但是C2只會存在一個,并且這三個Activity都在同一個task里面。但是C1->C2->C3->C2->C3->C1-C2,這樣的操作過程實際應該是如下這樣因為singleTask會把task中在其之上的其它Activity destory掉。
    操作:C1->C2 C1->C2->C3 C1->C2->C3->C2 C1->C2->C3->C2->C3->C1 C1->C2->C3->C2->C3->C1-C2
    實際:C1->C2 C1->C2->C3 C1->C2 C1->C2->C3->C1 C1->C2
    ??若是別的應用程序打開C2,則會新啟一個task。
    ??如別的應用Other中有一個activity,taskId為200,從它打開C2,則C2的taskIdI不會為200,例如C2的taskId為201,那么再從C2打開C1、C3,則C1、C3的taskId仍為201。
    注意:如果此時你點擊home,然后再打開Other,發現這時顯示的肯定會是Other應用中的內容,而不會是我們應用中的C1 C2 C3中的其中一個。
    singleInstance
    ??只有一個實例,并且這個實例獨立運行在一個task中,這個task只有這個實例,不允許有別的Activity存在。
    例如:
    ??加載該Activity時如果沒有實例化,他會創建新的Task后,實例化入棧,如果已經存在,直接調用 onNewIntent,該Activity的Task中不允許啟動其它的Activity,任何從該Activity啟動的其他Activity都將被放到其他task中,先檢查是否有本應用的task,沒有的話就創建。
    ??程序有三個ActivityD1,D2,D3,三個Activity可互相啟動,其中D2為singleInstance模式。那么程序從D1開始運行,假設D1的taskId為200,那么從D1啟動D2時,D2會新啟動一個task,即D2與D1不在一個task中運行。假設D2的taskId為201,再從D2啟動D3時,D3的taskId為200,也就是說它被壓到了D1啟動的任務棧中。
    singleInstance附加解釋:
    ???這種啟動模式比較特殊,因為它會啟用一個新的棧結構,將Activity放置于這個新的棧結構中,并保證不再有其他Activity實例進入。
    ???我們修改MainActivity的launchMode=”standard”,SecondActivity的launchMode=”singleInstance”,由于涉及到了多個棧結構,我們需要在每個Activity中顯示當前棧結構的id,所以我們為每個Activity添加如下代碼:
    TextView textview=(TextView)findViewById(R.id.tv); textview.setText("current tesk id"+this.getTaskId());
image.png
image.png

??我們發現這兩個Activity實例分別被放置在不同的棧結構中,關于singleInstance的原理圖如下

image.png

???上半部分圖我們看到從MainActivity跳轉到SecondActivity時,重新啟用了一個新的棧結構,來放置SecondActivity實例,然后按下后退鍵,再次回到原始棧結構;圖中下半部分顯示的在SecondActivity中再次跳轉到MainActivity,這個時候系統會在原始棧結構中生成一個MainActivity實例,然后回退兩次,注意,并沒有退出,而是回到了SecondActivity,為什么呢?是因為從SecondActivity跳轉到MainActivity的時候,我們的起點變成了SecondActivity實例所在的棧結構,這樣一來,我們需要“回歸”到這個棧結構。

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

推薦閱讀更多精彩內容