Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Activity啟動模式

Activity啟動模式

編輯:關於Android編程

最近學習了Activity的啟動模式,這裡記錄下,以便以後回顧

Activity有四種啟動模式,分別為:

* standard

* singleTop

* singleTask

* singleInstance

standard

默認情況下,系統會以standard模式來啟動activity,這種模式下系統會創建一個新的activity實例。

 

這裡寫圖片描述

 

singleTop

指定Activity的啟動模式為singleTop時,當被啟動的Activity B已經存在一個實例,並且位於任務棧的棧頂,這時候系統就不會生成一個新的Activity B,而是回調Activity B的onNewIntent函數

如下圖示

 

這裡寫圖片描述

 

可以看到,第二次啟動Activity B,系統並沒有創建新的Activity B的實例,而是回調了已經存在於任務棧棧頂的Activity B的onNewIntent函數。

這種模式適用於那些布局幾乎一樣,而內容存在變化的Activity,比如新聞類APP的新聞展示頁面就可以使用singleTop模式,這樣當用戶正處於具體新聞的展示頁面時,當用戶點擊任務欄裡面的推送新聞時,可以不用創建新的Activity而直接用已經存在的Activity,節省資源的開銷。

singleTask

singleTask可以理解為single in desired task,即在所指定的task裡面只能存在一個實例。每一個Activity都可以在manifest裡面通過TaskAffinity指定自己所在的task的名稱,如果不指定的話,系統將使用默認的任務棧。

啟動一個singleTask的Activity B,系統會做以下幾步操作:

1.尋找Activity所在的task(假定名字為A),如果A不存在,則創建task A

2.在task A中尋找Activity B,如果B已存在,那麼將B之上的所有Activity出棧,然後回調Activity B的onNewIntent方法,如果B不存在,那麼創建B,並將之壓入棧A中。

以下是我自己嘗試的幾個singleTask例子。

以下例子均省略A的啟動步驟

例子1

有3個Activity:

* A standard

* B singleTask,未指定TaskAffinity

* C singleTask,未指定TaskAffinity

啟動順序A->B->C

singleTask模式的Activity B啟動時系統會去尋找其TaskAffinity指定的任務棧,而這裡我並沒有設置TaskAffinity屬性,故而系統會使用默認的值(程序包名)去尋找任務棧,找到的任務棧(task)就是默認的任務棧,即A所在的任務棧。然後在任務棧中去尋找Activity B,由於當前並沒有B存在,故而系統會創建一個新的實例壓入棧中,然後通過B啟動C過程是一樣的。

整個過程中並沒有創建新的任務棧(task)

 

這裡寫圖片描述

 

例子2

有3個Activity:

* A standard

* B singleTask,指定TaskAffinity為feitengbing

* C singleTask,未指定TaskAffinity

啟動順序A->B->C

 

這裡寫圖片描述

 

圖中紅色的是默認的任務棧,當啟動Activity B時,由於B指定了TaskAffinity為feitengbing,故而系統會去創建名為feitengbing的task(圖中的藍色部分),然後在這個新創建的task中創建Activity B的實例。當啟動C的時候又不一樣了,由於C沒有有指定TaskAffinity,故而系統會按照默認值(程序的包名)來尋找任務棧,找到的task是默認的任務棧,及我們圖中的紅顏色任務棧,系統會把這個task挪到前台(foreground),然後在其中去尋找C,由於C不存在,故而創建一個新的C的實例。

當按返回鍵回退時你就會發現,原來的啟動順序是 A -> B -> C,但是回退順序卻是C -> A -> B.正如上圖所描述的那樣

例子3

有3個Activity:

* A standard

* B singleTask,指定TaskAffinity為feitengbing

* C standard

 

這裡寫圖片描述

 

這個例子區別於例子2在於C使用standard啟動,故而會使用直接在當前task中創建新實例,這次在往回退時其順序和啟動順序剛好相反 C -> B -> A

例子4

在網上看到有人說如果launchMode指定為singleTask或者singleInstance時,若不指定TaskAffinity屬性,那麼launchMode就會被系統忽略,那麼就找個例子試一下

 

這裡寫圖片描述

 

這個例子有 A.B.C.D 4個Activity,其中B的啟動模式為singleTask,並且沒有指定TaskAffinity屬性,這個例子運行的結果,如上圖所示,在Activity D中啟動Activity B,系統並沒有去創建新的Activity B,而是遵循singleTask模式,去相應的任務棧中尋找Activity B,由於當前任務棧是存在Activity B的,故而清空了Activity B上面的其他Activity,然後回調Activity B的onNewIntent函數,這裡面的操作都是按照singleTask模式來執行的,結合上面的例2可以得出,當Activity指定啟動模式為singleTask,但沒有指定TaskAffinity屬性時,系統並沒有忽略該啟動模式。

singleInstance

看名字就知道是單例模型,這個模式下啟動的Activity系統會為之單獨創建一個task(即使沒有指定TaskAffinity屬性也會創建),這個新創建的task中有且僅有該Activity,如果在這個Activity裡面去啟動其他的Activity,其效果就相當於在用於啟動Activity的intent裡面加上FLAG_ACTIVITY_NEW_TASK標志位。

 

這裡寫圖片描述

 

上圖中啟動Activity C時,無論C是什麼啟動模式(圖片裡面C是standard模式),都不會在Activity B所在的task裡面創建新Activity,而Activity C到底會出現在哪個task裡面,這個就跟其具體的啟動模式有關了。

以上就是Activity在manifest中靜態注冊的四種啟動模式。

除了在manifest中靜態注冊之外,我們還可以在啟動Activity的intent當中指定標志位來達到上述目的,可以設置的標志位有以下這些:

FLAG_ACTIVITY_CLEAR_TASK 清空activity指定的任務棧(taskAffinity指定,或者默認),再啟動Activity

FLAG_ACTIVITY_CLEAR_TOP 相當於singleTask模式下的Activity存在時的情況

FLAG_ACTIVITY_FORWARD_RESULT

FLAG_ACTIVITY_NEW_DOCUMENT

FLAG_ACTIVITY_NEW_TASK,當我們在非Activity上下文(Service,Application等)裡啟動Activity時,無論Activity是什麼啟動模式,都必須添加這個標志位

FLAG_ACTIVITY_PREVIOUS_IS_TOP

FLAG_ACTIVITY_REORDER_TO_FRONT

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_SINGLE_TOP 相當於singleTop模式

FLAG_ACTIVITY_TASK_ON_HOME

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved