Android-啟動模式task-lunchmodle-intent flag 總結

來源:互聯網
上載者:User

標籤:


總結:
  • 同一task內的activity可以是來自不同進程的activity
  • 棧內的activity不會重新排序,只能push或者pop
  • standard模式允許多執行個體,可以在不同的task
  • singleTask的activity只會存在一個執行個體
  • singleTask的activity如果設定了獨立的taskAffinity屬性值,啟動時就會在新的task中,否則會在已有task中
  • singleTask的activity啟動時,它會在目標task(新的task或者已有task)中查看是否已經存在相應的activity執行個體,如果存在,就會把位於這個activity執行個體上面的activity全部銷毀(pop, destroy)掉,即最終這個activity執行個體會位於任務的堆棧頂端中
task

task是一個從使用者角度出發的概念,它是一些activity的組合,它們組合起來是為了讓使用者完成某一件工作(或者說操作)。

task內的activity們以棧的形式組織起來,也就是back stack了。棧內的activity不會重新排序,只能push或者pop。棧內的activity可以來自不同的app,因此可以是運行在不同的進程,但是它們都屬於同一個task內。

安卓系統是即時多task系統,使用者可以隨意在多個task之間切換。當一個task的棧內所有activity都pop之後,task也就銷毀了。有時系統為了回收記憶體,會銷毀activity,但是task不會銷毀。

activity在manifest中有launchMode選項,可以配置其啟動的模式。標準模式下,允許一個activity同時存在多個執行個體,既可以在同一個task,也可以在不同task。manifest可以指定launchMode,intent可以指定intent flag,前者供被啟動者使用,後者供啟動者使用,同時使用時後者會覆蓋前者。

launchMode
  • standard,預設模式,允許多執行個體
  • singleTop,相比於standard,有新的啟動請求時,只有在目標activity處於當前棧頂時,才會調用onNewIntent()而不建立新執行個體,其他情況都和standard一致
  • singleTask,(這段摘自老羅的部落格)設定了”singleTask”啟動模式的Activity,它在啟動的時候,會先在系統中尋找屬性值affinity等於它的屬性值taskAffinity的任務存在;如果存在這樣的任務,它就會在這個任務中啟動,否則就會在新任務中啟動。因此,如果我們想要設定了”singleTask”啟動模式的Activity在新的任務中啟動,就要為它設定一個獨立的taskAffinity屬性值。如果設定了”singleTask”啟動模式的Activity不是在新的任務中啟動時,它會在已有的任務中查看是否已經存在相應的Activity執行個體,如果存在,就會把位於這個Activity執行個體上面的Activity全部結束掉,即最終這個Activity執行個體會位於任務的堆棧頂端中。
  • singleInstance,和singleTask相比,不同點在於singleInstance activity所在的task只會有這一個activity
  • 返回導航:singleTask和singleInstance啟動的activity,儘管可能不在同一個task,但是仍然會回到原來的activity;但是singleTask可能會存在back stack“拼接”的情況
launchMode驗證測試

主要測試的是singleTask這一屬性,其他的文檔描述都比較清楚,也不容易產生誤解。兩組實驗,不設定taskAffinity和設定taskAffinity時,singleTask的行為。對比兩者“最近任務”,dumpsys,logcat,返回導航的差異。

測試1

不設定taskAffinity,MainActivity -> SingleTaskFirstActivity -> SimpleActivity -> SingleTaskSecondActivity -> 選擇圖片Intent,再一路返回。

最近任務內只能看到一個TaskDemo的任務,dumpsys的結果如下:

所有的activity均在同一個task內,驗證了老羅的結論。另外注意標紅的兩處,它們的ProcessRecord對象不同,ImageGallery和SingleTaskActivity處於不同的進程,也驗證了前文所述“可以運行在不同的進程”。

logcat日誌如下:

一路返回依次回到SingleTaskSecondActivity, SimpleActivity, SingleTaskFirstActivity,MainActivity, 案頭。

測試2

設定SingleTaskFirstActivity的taskAffinity為單獨的值,MainActivity -> SingleTaskFirstActivity。

通過最近任務可以看到,有了兩個TaskDemo的任務。而dumpsys結果如下:

可以看到,MainActivity和SingleTaskFirstActivity運行在了兩個不同的task裡面(棧底為MainActivity的t225, 棧底為SingleTaskFirstActivity的t226),但是他們仍屬於同一進程。

我們接著啟動SimpleActivity,再通過最近任務切換回t225,並且也啟動SimpleActivity,這時通過dumpsys結果如下:

SimpleActivity同時存在兩個執行個體,他們的hashCode是不同的,目前處於resumed狀態的是在t225中的執行個體。

而通過查看logcat:

我們同樣發現SimpleActivity被建立了兩個執行個體。

此時我們通過最近任務切換回t226,並在此啟動SingleTaskSecondActivity,查看dumpsys,然後再切換回t225也啟動SingleTaskSecondActivity,查看dumpsys和logcat:

我們可以看到儘管第一次啟動SingleTaskSecondActivity是在t226,但是SingleTaskSecondActivity執行個體卻運行在t225中,為什麼呢?因為SingleTaskSecondActivity並沒有設定taskAffinity屬性,所以它和MainActivity將會運行在同一個task中!和老羅的分析一致。而第二次啟動時,並未建立新的SingleTaskSecondActivity執行個體,而是調用了它的onNewIntent方法,和文檔描述一致。

現在我們測試一下返回導航,依次按下返回鍵,觀察每次回到的activity,以及每次dumpsys的結果,以及logcat的結果:

第一次回到了t225的SimpleActivity,dumpsys:

第二次回到了t225的MainActivity,dumpsys:

第三次回到了t226的SimpleActivity,dumpsys:

第四次回到了t226的SingleTaskFirstActivity,dumpsys:

最後一次返回就回到了案頭。

logcat日誌如下:

從上面的返迴路徑來看,確實驗證了developer文檔上關於back stack“拼接”的情況的描述,即:並不是按照most recent first的順序返回的,而是優先把一個task的back stack(t225) pop完畢之後,再pop下一個task的back stack(t226)。

測試3

基於測試2的版本,MainActivity -> SingleTaskFirstActivity -> SimpleActivity,再切換回MainActivity,再啟動SingleTaskFirstActivity。

查看最近任務,仍然有兩個task,但是查看dumpsys以及logcat:

我們可以看到,第一次啟動的SimpleActivity就被pop(destroy)了,從而把未在棧頂的SingleTaskFirstActivity提到了棧頂。這也驗證了back stack內的activity不會重新排序,最會pop和push的事實。

Intent flag

只要搞清楚了launchMode中容易產生誤解的地方,對於intent flag來說,只需要記住一點即可:intent flag可以覆蓋launchMode的設定。為了避免內容過於冗長,本文就不對intent flag進行詳細的測試分析了。

總結
  • 同一task內的activity可以是來自不同進程的activity
  • 棧內的activity不會重新排序,只能push或者pop
  • standard模式允許多執行個體,可以在不同的task
  • singleTask的activity只會存在一個執行個體
  • singleTask的activity如果設定了獨立的taskAffinity屬性值,啟動時就會在新的task中,否則會在已有task中
  • singleTask的activity啟動時,它會在目標task(新的task或者已有task)中查看是否已經存在相應的activity執行個體,如果存在,就會把位於這個activity執行個體上面的activity全部銷毀(pop, destroy)掉,即最終這個activity執行個體會位於任務的堆棧頂端中

Android-啟動模式task-lunchmodle-intent flag 總結

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.