天天看點

android launchMode了解以及應用場景

在我們寫應用的時候,常常涉及多個activity元件之間的跳轉。比如說某個資訊的頁面中,點選下一篇資訊跳轉相同的頁面,隻有頁面的資料不一樣。一般情況下我不會注意launchMode 這個屬性,隻會使用預設的,這樣會産生大量重複的activity。那是因為之前不了解,是以特此研究學習。

1.如何指定launchMode

基本上我們可以直接指定一個launchMode屬性在AndroidManifest.xml 檔案中

<activity
    android:name=".views.MainActivity"
    android:screenOrientation="portrait"
    android:launchMode="singleTop"/>
           
存在4中類型的launchMode
android launchMode了解以及應用場景

2.standard 模式介紹

這是預設模式,每次激活Activity時都會建立Activity執行個體,并放入任務棧中。

activity設定為這個模式的行為是一個新的活動,每一個意圖發送,将總是被建立的工作分開。想象一下,如果有10的意圖去寫郵件,應該有10個活動的開展為每一個單獨的意圖。是以,有可能是一個無限數量的這種活動在一個裝置啟動。

2.1 5.0 版本之前

這種activity将被建立,并放置在堆棧的頂部,在同一個task,發送一個Intent。

android launchMode了解以及應用場景

下面的一個圖檔顯示當我們将一個圖像分享到一個标準的activity時會發生什麼。它将被堆疊在同一個任務中,雖然他們是從不同的應用程式。

android launchMode了解以及應用場景

這是你将在任務管理器中看到的。(可能有點奇怪)

android launchMode了解以及應用場景

如果我們換到另一個應用程式,然後再切換回Gallery,我們仍将看到頂上畫廊的任務launchMode标準的地方。是以,如果我們需要做任何與Gallery相關的操作,我們必須完成目前activity的事情或者關閉目前的activity,才可以回到原來的地方。

2.2 5.0版本之後

如果這些活動都來自同一個應用程式,它能夠像5.0之前一樣,堆疊的任務

android launchMode了解以及應用場景

但是在某些情況下,我們發送的Intent 來自不同的intent,新的task将被建立,新建立的activity将被放置在下面的根activity中。

android launchMode了解以及應用場景

下面是我們重任務管理器中看到的和5.0之前是有差別的

android launchMode了解以及應用場景

這是因為任務管理系統的改進Lollipop使它更有意義。Lollipop,你可以切換回畫廊,因為它們是不同的任務。你可以發射另一個意圖,一個新的任務将被建立,以服務一個與前一個相同的意圖。

android launchMode了解以及應用場景

2.3 應用場景舉例

這種activity的一個例子是一個組成電子郵件activity或社交網絡的狀态張貼activity。如果你考慮一個可以單獨工作的活動,為一個單獨的意圖服務。

舉例引用:

AlarmClock uses standard. The user can launch multiple instances of this activity and these instances can be part of any task and anywhere in the activity stack. As a fairly simple application it doesn’t really demand tight control of its activity

鬧鐘的使用 standard。使用者可以啟動此activity的多個執行個體,這些執行個體可以是任何任務的一部分,也可以是活動堆棧中的任何地方的一部分。作為一個相當簡單的應用,它并不真的需要它的activity的嚴格控制

3.singleTop 模式介紹

singleTop模式。它的作用幾乎和standard一樣。唯一不同的是,如果已經存在在棧頂在對方的任務一個同類型的活動執行個體,不會有任何新的activity創造,而是被發送到一個存在的activity執行個體通過onNewIntent() 方法的意圖,即會重用該執行個體調用目前activity的onNewIntent() 方法。

android launchMode了解以及應用場景

在singleTop模式,對于新的Intent,你要負責onCreate() 和 onNewIntent() 來控制使它适用于所有的情況。

3.1 應用場景舉例

這個模式的一個示例用例是一個搜尋功能。我們想創造一個搜尋框,它會帶你到一個SearchActivity看到搜尋結果。為了更好的使用者體驗,我們通常總是把一個搜尋框,在搜尋結果頁面以及讓使用者做另一個搜尋無壓回。

現在想象一下,如果我們總是推出服務新的搜尋結果的新searchactivity,10次搜尋将産生10個新activity。這将是非常奇怪的,當你按下回來,因為你必須要10次,通過這些搜尋結果activity,以獲得回你的根activity。相反,如果在棧頂 searchactivity,我們最好送一個Intent的一個存在的activity執行個體,讓它更新搜尋結果。現在隻會有一個searchactivity放在棧頂,你可以簡單地按下按鈕就回一次回到以前的活動。現在有更多的意義。

反正singleTop 作用相同的任務棧。如果你期望一個Intent被發送到一個存在的活動放置在任何其他任務的頂部,我必須讓你失望,說它不工作。如果Intent是從另一個應用程式發送到singleTop activity,新的activity将推出在同一方面作為standard launchMode。

注意:5.0之前:放在對方的任務,5.0以及之後(Lollipop):一個新的任務被建立。

舉例引用:

BrowserBookmarksPage uses singleTop. While there can be multiple instances of this activity, if there is already one at the top of the task’s activity stack it will be reused and onNewIntent() will be called. This way you only have to hit back once to return to the browser if the bookmarks activity is started multiple times.

浏覽書簽頁面使用singleTop。雖然有可能是這一活動的多個執行個體,如果已經有一個在任務棧頂的活動将被重用和onnewintent()将被調用。這樣,你隻需要傳回一次傳回到浏覽器,如果書簽activity是開始多次。

4.singleTask 模式介紹

這種模式和 standard singleTop完全不同。采用singleTask launchMode 的activity是允許在系統中隻有一個執行個體(又名Singleton)。如果系統中有一個存在的活動執行個體,整個任務将執行個體将被移動到頂部,Intent将通過onnewintent()方法傳遞。否則,新的activity将被建立并放置在适當的任務中。

4.1 在同一個應用中

如果沒有在系統中還存在singleTask活動執行個體,新一将要建立簡單的放在棧頂在同一個任務。

android launchMode了解以及應用場景

但如果有一個存在的singleTask activity執行個體放在上面,會自動地破壞(以恰當的方式 生命周期觸發)其他的activity,讓該執行個體出現在棧頂。同時,一個Intent是通過的onnewintent()方法送到singleTask activity。

android launchMode了解以及應用場景

在使用者體驗上沒有一個很好的感覺,但它是這樣設計的…

The system creates a new task and instantiates the activity at the root of the new task.

注意:系統建立一個新任務并執行個體化活動新任務的根。

但從實驗中,它似乎不工作。單一任務活動仍棧頂上的任務的活動堆棧。從中我們可以看到什麼dumpsys活動指令顯示。

android launchMode了解以及應用場景

如果你想讓一個活動就像描述singleTask文檔:建立一個新的任務,把活動作為一根活動。你需要指定的taskAffinity屬性為singleTask這樣的活動。

android launchMode了解以及應用場景

下面是啟動SingleTaskActivity 的結果示例

android launchMode了解以及應用場景
android launchMode了解以及應用場景
考慮是否使用taskAffinity的行為,這是你的工作。

4.2 與另一個應用合作

一旦一個 Intent 是從另一個應用程式發送,并且沒有在系統中建立的任何活動執行個體,新的任務将建立一個新建立的活動作為一個根活動。

android launchMode了解以及應用場景
android launchMode了解以及應用場景

除非有一個應用程式,是一個擁有調用singleTask activity存在的任務,創造了新的活動會放在上面。

android launchMode了解以及應用場景

如果有任何任務存在的活動執行個體,整個任務将被移動到頂部和每個單獨的activity在singleTask activity上的将會被銷毀按照正常的生命周期。如果按下後退按鈕,使用者必須在傳回到調用方任務之前通過堆棧中的活動進行。即先關閉圖中task#1 中的activity,再回到task#2.

android launchMode了解以及應用場景

4.3 應用場景示例

這種模式的一個示例用例是任何一個入口點活動例如電子郵件用戶端的收件箱頁面或社交網絡的時間軸。無論如何,你必須明智地使用這個模式,在這種模式下活動可能會被破壞。

BrowserActivity uses singleTask. There is only one browser activity at a time and it doesn’t become part tasks that send it intents to open web pages. While it might return to whatever most recently launched it when you hit back it is actually fixed at the bottom of its own task activity stack. It will share its task with activities that it launches like bookmarks

browseractivity使用singleTask。隻有一個浏覽器的活動的時間,它不成為一部分的任務,把它試圖打開網頁。雖然它可能會傳回到任何最近推出的它,當你回擊它實際上是固定在其自己的任務活動棧的底部。它将分享它的任務與活動,它推出像書簽.

5.singleInstance 模式介紹

這種模式是相當接近singleTask,單個activity執行個體可以存在于系統中。不同的是任務舉行這次活動,隻能有一個活動。如果這種活動調用另一個活動,一個新的任務将被自動建立,以放置新的活動。同樣,如果singleInstance活動被被調用,新的任務将會被建立放置這個activity。

無論如何,結果是相當奇怪的。從dumpsys提供的資訊,它在系統中有兩個任務,但隻有一個出現在任務管理器中最新的一個決定,移動到頂部。是以,雖然有一個任務,仍然在背景工作,但我們不能切換到前台。根本沒有任何意義。

這是singleInstance活動被調用同時一個activity已經存在在task 中。

android launchMode了解以及應用場景

但是在任務管理器中看不到新的task

android launchMode了解以及應用場景

由于這項任務可能隻有一個活動,我們無法切換回任務# 1了。這樣做的唯一方法是重新啟動的應用程式,但看來singleInstance任務将被隐藏在背景。

簡單地配置設定taskAffinity屬性到singleInstance活動使任務管理多個任務。
<activity
    android:name=".SingleInstanceActivity"
    android:label="singleInstance launchMode"
    android:launchMode="singleInstance"
    android:taskAffinity="">
           

這樣将看到被隐藏的task

android launchMode了解以及應用場景

5.1 應用場景示例

AlarmAlert uses singleInstance. Only one alert activity at a time and it is always its own task. Anything it launches (if anything) becomes part of its own new task

alarmalert使用singleInstance。隻有一個警報活動在一個時間,它總是自己的任務。它啟動的任何東西(如果有的話)成為它自己的新任務的一部分

這種模式很少被使用。一些真正的用例是一個用于啟動或應用程式的活動,你是100%肯定隻有一個活動。總之,我建議你不要使用這種模式,除非它是真的有必要。

6.Intent Flags

launchMode是規定你自己的Activity啟動的行為模式,而Intent.Flag是你期望由你啟動的其他的Activity是什麼樣的行為模式

除了配置設定啟動模式直接在AndroidManifest.xml,我們也能夠通過所謂的意圖示志更多的行為配置設定,例如:

Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
           

7.總結以及參考資料

7.1 總結

[1] standard 模式

這是預設模式,每次激活Activity時都會建立Activity執行個體,并放入任務棧中。

[2] singleTop 模式

如果在任務的棧頂正好存在該Activity的執行個體,就重用該執行個體( 會調用執行個體的 onNewIntent() ),否則就會建立新的執行個體并放入棧頂,即使棧中已經存在該Activity的執行個體,隻要不在棧頂,都會建立新的執行個體。

[3] singleTask 模式

如果在棧中已經有該Activity的執行個體,就重用該執行個體(會調用執行個體的 onNewIntent() )。重用時,會讓該執行個體回到棧頂,是以在它上面的執行個體将會被移出棧。如果棧中不存在該執行個體,将會建立新的執行個體放入棧中。

[4] singleInstance 模式

在一個新棧中建立該Activity的執行個體,并讓多個應用共享該棧中的該Activity執行個體。一旦該模式的Activity執行個體已經存在于某個棧中,任何應用再激活該Activity時都會重用該棧中的執行個體( 會調用執行個體的 onNewIntent() )。其效果相當于多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。

最後,資料什麼的都看完了,學習到了很多。最近在寫項目會用到launchMode,将以前模糊不明白的地方,搞懂一些。磨刀不誤砍柴工說的很對,是以先看資料學習,再通過項目練手加深印象。

7.2 參考資料

1.Understand Android Activity’s launchMode: standard, singleTop, singleTask and singleInstance

2.http://stackoverflow.com/questions/2626218/examples-for-android-launch-modes

3.基礎總結篇之二:Activity的四種launchMode

4. android launchmode(四種啟動模式)應用場景及執行個體

5.Android activity launchMode與Intent.Flag關系