在進入啟動模式學習前我們先了解一下:
1、一個應用程式一般都是由多個activity組成的。
2.任務棧(task stack)(别名back stack後退棧) 記錄存放使用者開啟的activity。
3、一個應用程式一被開啟系統就給他配置設定一個任務棧,當所有的activity都退出的時候,任務棧就清空了。
4、任務棧的id是一個integer的資料類型 自增長的。
5、在android作業系統裡面會存在多個任務棧,一個應用程式一個任務棧。
6、桌面應用和一般的應用程式是一樣的,任務棧的行為也是一樣。
7、預設情況下, 關閉掉一個應用程式,清空了這個應用程式的任務棧。應用程式的程序還會保留。
下面進入正題
Activity的啟動模式
Android為了使我們能夠打破預設的堆棧先進後出模式,提供了兩個種方式:一種是在AndroidManifest.xml定義Activity時指定它的加載模式,另一種是在用Intent開啟一個Activity時,在Intent中加入标志。如果兩種方式都用了,則後者的優先級更高。
兩種方式的差别在于,前者在于描述自己,向别的Activity等聲明你們如何來加載我;而後者則是動态的,指出我要求你(要啟動的Activity)以某種啟動模式啟動。
根據Activity的不同的啟動模式,它在Task Stack(别名 BackStack 回退棧)中的狀态是不一樣的。Activity可以通過AndroidManifest.xml清單檔案配置,在<Activity />節點中的android:launchMode屬性設定。它有四個選項:
- standard
- singleTop
- singleTask
- singleInstance
standard:标準啟動模式,也是預設啟動模式,如果不設定android:launchMode屬性的話。standard模式下的Activity會依照啟動的順序壓入Task Stack中。
下圖是standard模式下,Activity的壓棧和回退操作示意圖:
singleTop:頂部單例模式,這種Activity啟動模式,啟動一個Activity的時候如果發現Task Stack的棧頂已經存在這個Activity了,就不會去重新建立新的Activity對象,而是複用這個棧頂已經存在的Activity對象,避免同一個Activity被重複開啟。
下圖是singleTop模式下,Activity的壓棧和回退操作示意圖:
singleTop的應用場景很多,一般适用于可以複用而又有多個開啟管道的Activity,避免當一個Activity已經開啟并獲得焦點後,再次重複開啟。比如說浏覽器書簽頁面, 避免棧頂的activity被重複的建立,解決使用者體驗問題。,就是一個singleTop模式的Activity。Android的浏覽器是基于WebKit核心編寫的,它是支援JavaScript腳本語言的,可以通過JavaScript腳本設定浏覽器書簽,這樣如果存在多個頁面存在儲存書簽的JavaScript腳本,就會導緻書簽頁面被多次開啟,是以書簽頁面被設定為singleTop模式,這樣可以避免在儲存多個書簽的時候重複開啟書簽頁面。 應用場景:
singleTask:開啟一個Activity的時候,檢查Task Stack裡面是否有這個Activity的執行個體存在,如果存在的話,BackStack裡這個Activity上所有的其他Activity都被彈出。
下圖是singleTask模式下,Activity的壓棧和回退操作示意圖:
singleTask的的适用場景為一般程式的首頁面,當回退到首頁面的時候,清除Task Stack中,它之上的所有Activity,這樣避免程式導航邏輯的混亂。比如Android系統的浏覽器的首頁面,就是singleTask模式的,上面提到,android下浏覽器是Webkit核心的,它是由C語言編寫的,而每次打開新的網頁如果重新開啟一個Activity,是非常耗費系統資源的(需要解析HTML、Script腳本),是以被設定為singleTask模式,這樣在浏覽器應用裡,無論打開多少個頁面,使用的都是同一個Activity。是以以後如果存在很耗費系統資源的Activity,可以考慮使用singleTask開啟模式。
singleInstance:被标記為singleInstance啟動模式的Activity,在啟動的時候,會開啟一個新的Task Stack,這個BackStack裡隻有一個Activity的執行個體存在,并且把這個Task Stack獲得焦點。這是一種很極端的模式,它會導緻整個裝置的作業系統裡,隻會存在一個這個Activity示例,無論是從何處被啟動的。
下圖是singleInstance模式下,Activity的壓棧和回退操作示意圖:
singleInstance一般适用于需要在系統中隻存在一個執行個體的場景,比如Android系統的來電頁面,多次來電均使用的是一個Activity。
當然,在Android中,除了在AndroidManifest.xml清單檔案中配置LauncherMode屬性外,還可以在代碼中設定啟動模式。在元件中,啟動一個Activity,需要用到startActivity()方法,其中傳遞一個Intent,可以使用Intent.setFlags(int flags)來設定新啟動的Activity的啟動模式,而通過代碼設定Activity的啟動模式的方式,優先級要高于在AndroidManifest.xml清單檔案中的配置。
Intent.setFlag(int flags)方法傳遞的一個整形的資料,被Android系統設定為了常量:
- FLAG_ACTIVITY_NEW_TASK:這個辨別會使新啟動的Activity獨立建立一個Task。
- FLAG_ACTIVITY_CLEAR_TOP:這個辨別會使新啟動的Activity檢查是否存在于Task中,如果存在則清除其之上的Activity,使它獲得焦點,并不重新執行個體化一個Activity,一般結合FLAG_ACTIVITY_NEW_TASK一起使用。
- FLAG_ACTIVITY_SINGLE_TOP:等同于在LauncherMode屬性設定為singleTop。