每日一道面試題(第4期)---launchMode的應用場景

零零碎碎的東西老是記不長久,僅僅學習別人的文章也只是他人咀嚼後留下的殘渣。無心中發現了這個每日一道面試題,想了想若是隻是簡單地去思考,那麼不只會收效甚微,甚至難一點的題目本身可能都懶得去想,堅持不下來。因此不如把每一次的思考、理解以及別人的看法記錄下來。不只加深本身的理解,更要激勵本身堅持下去。java

launchMode簡介

what(是什麼)

是Activity的一種配置屬性,表示Activity由哪一種方式啓動android

how(怎麼用)

有兩種配置方式:git

  • 在manifest清單文件中配置默認啓動屬性。

manifest配置launchMode

  • 在java代碼中,啓動Activity時指定啓動方式,經過inent.addFlags()方法,這裏面經常使用的有四種。
    • Intent.FLAG_ACTIVITY_NEW_TASK
    • Intent.FLAG_ACTIVITY_SINGLE_TOP
    • Intent.FLAG_ACTIVITY_CLEAR_TOP
    • Intent.FLAG_ACTIVITY_CLEAN_TASK

具體的使用以及各類搭配使用說明能夠看這個Android 之Activity啓動模式(二)之 Intent的Flag屬性,寫的很詳細。github

why(爲何須要)

在不一樣的場景考慮到不一樣形式的Activity實例的複用,選擇不一樣的加載方式。面試

四種launchMode啓動模式

介紹啓動模式前,咱們先來了解下Android的Activity管理機制。瀏覽器

Android採用Task來管理多個Activity,當咱們啓動一個應用時,Android就會爲之建立一個Task,而後就是啓動這個應用程序的入口Activity,並將實例放入Task。app

Android並無爲Task提供任何的API,咱們沒法真正的訪問Task,只有一個getTaskId方法得到所在Task的Id。Task經過棧的方式管理Activity實例,包括先進後出、入棧出棧方式都是同樣的。學習

Task棧

standard模式

默認的啓動模式。每次啓動一個Activity,都會建立一個新的Activity實例放在Task棧頂。這個Task棧是啓動新的Activity的Activity所在的Task棧。那麼這時候就會有特殊的狀況,若是是service或者Application啓動的Activity,並無Task棧,這時就須要咱們經過addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)指定標記,建立一個新的Task。ui

standard示例

app的大多數Activity皆採用這種啓動模式。做爲開發者,咱們考慮到的就是用戶在操做每一個頁面後,即便之間有重複的界面,按回退鍵也能夠按照剛剛操做的順序回退。spa

singleTop模式

這種模式存在兩種狀況:

  • Task棧頂不是要啓動的Activity實例,這時和standard模式沒有區別
  • Task棧頂是要啓動的Activity實例,那麼就會複用這個實例,而且回調該Activity的onNewIntent方法。因爲不會建立Activity實例,因此不會回調其餘方法。

singleTop

通常應用於通知詳情頁或者聊天界面,即經過點擊通知欄消息進入Activity。能夠避免有屢次通知消息經過點擊而產生較多Activity實例。加強Activity的複用性。

singleTask

這種模式有三種狀況。

  • Task棧中不存在要啓動的Activity實例,這時和standard模式沒有任何區別
  • Task棧中存在要啓動的Activity實例,且此實例在棧頂,這時和singleTop模式沒有區別
  • Task棧中存在要啓動的Activity實例,且此實例不在棧頂。這時會移除此實例上的全部Activity實例,使此實例置於Task棧頂,並複用此實例,回調onNewIntent方法

也就是說這是一種棧內的單例模式。這種模式下還能夠經過manifest文件中的taskAffinity屬性來指定要加載的Task棧。

<activity 
    android:name=".activitys.MainActivity"
    android:launchMode="singleTask"
    android:taskAffinity="com.gl.task"/>
複製代碼

關於taskAffinity的值:每一個Activity都有taskAffinity屬性,這個屬性指出了它但願進入的Task。若是一個Activity沒有顯式的指明該Activity的taskAffinity,那麼它的這個屬性就等於Application指明的taskAffinity,若是Application也沒有指明,那麼該taskAffinity的值就等於包名。

singleTask示例

這種模式通常應用於app的主頁,在退出應用程序的時候不須要退出其餘的Activity,由於主頁通常置於Task棧底部。或者該頁面可能會被其餘應用程序喚醒,好比瀏覽器首頁。

singleInstance模式

這種模式算是一種全局的單例模式,即只要有任何一個棧存在此Activity實例,就會複用此實例,回調onNewIntent方法。若是此實例不存在,那麼就會建立新的Task棧,並放入Activity實例。

也就是說,這種模式下的Activity實例只有兩種形式。

  • 不存在此實例
  • 存在此實例,且只在一個Task棧中而且該Task中只有該實例

singleInstance實例

這種模式通常應用於鬧鐘響鈴界面、撥打接聽電話界面等系統界面,確保此Activity實例只能存在一個。 常應用於獨立棧操做的應用,如鬧鐘的提醒頁面,當你在A應用中看視頻時,鬧鐘響了,你點擊鬧鐘提醒通知後進入提醒詳情頁面,而後點擊返回就再次回到A的視頻頁面,這樣就不會過多幹擾到用戶先前的操做了。

另外啓動其餘應用程序中的Activity的操做,在5.0以前新啓動的Activity實例會放入啓動的Intent所在的Task棧內,雖然他們並不屬於同一應用程序。這好像並不怎麼合理,因此在5.0後會建立一個新的Task棧存放外部應用程序的Activity實例

相關文章
相關標籤/搜索