編輯:關於Android編程
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
0 史前階段: Android操作系統最早的一個版本是2007年11月5日發布的Android beta,作為一個面向開發者的軟件開發
先放個gif。。最終效果如果: 主要演示了Android從服務器下載文件,調用Notification顯示下載進度,並且在下載完畢以後點擊通知會跳轉到安裝APK的界面,演
View的Draw時序圖前面幾篇通過對View樹的measure和layout過程分析事,接下來將結合前兩步得到的測量值及在視圖中的位位置,開始進行繪制操作,一步比一步復
前言本文是通過閱讀各種文章及代碼,總結出來的,其中難免有些地方理解得不對,歡迎大家批評指正。顯示系統基礎知識定義在一個典型的顯示系統中,一般包括CPU、GPU、displ