標籤:android 任務棧 任務棧模式 activity 生命週期
- Activity的生命週期
- 橫豎屏切換問題
- 任務棧的概念
- Activity的4種啟動模式
Activity的生命週期
Activity整個的生命週期如下所示,這張圖是從Android API上扒下來了,我覺得API上關於生命週期已經講解的很詳細了,我也就不囉嗦了,就簡要的說下自己的一些總結:
-
做工作中,你可能感興趣的三個關鍵環
-
① 完整生命週期
-
② 可見生命週期
-
③ 可互動生命週期
,圖中的周期都是大的包括小的:
-
在實際工作中的使用
-
①onResume可見, 可互動.。把動態重新整理的操作啟動。
-
②onPause部分可見, 不可互動. 把動態重新整理的一些操作, 給暫停了。
-
③onCreate 初始化一些大量的資料
-
④onDestroy 把資料給釋放掉, 節省記憶體。
橫豎屏切換問題
橫豎屏切換時,預設情況下會把activity先銷毀再建立,在類似手機遊戲這一類的應用中,這個體驗是非常差的。不讓Activity在橫豎屏切換時銷毀,只需要在資訊清單檔聲明Activity時配置<activity>節點的幾個屬性即可,其方式如下:
android:configChanges="orientation|keyboardHidden|screenSize"
-
解釋
-
①configChange=”orientation”螢幕方向改變:不讓螢幕在切換時重新建立activity
-
②sreensize 螢幕大小
-
③keyboardHidden是軟鍵盤,如果切換畫面,軟鍵盤會去判斷螢幕大小是否合適顯示軟鍵盤,在判斷過程中會重啟activity
-
設定橫屏或者豎屏
-
android:screenOrientation=”portrait” 豎屏
-
android:screenOrientation=”landscape”橫屏
任務棧的概念
-
任務棧是用來提升使用者體驗而設計的:
-
(1) 程式開啟時就建立了一個任務棧, 用於儲存當前程式的activity,所有的activity屬於一個任務棧。
-
(2) 一個任務棧包含了一個activity的集合, 去有序的選擇哪一個activity和使用者進行互動:只有在任務棧棧頂的activity才可以跟使用者進行互動。
-
(3) 任務棧可以移動到後台, 並且保留了每一個activity的狀態. 並且有序的給使用者列出它們的任務, 而且還不丟失它們狀態資訊。
-
(4) 退出應用程式時:當把所有的任務棧中所有的activity清除出棧時,任務棧會被銷毀,程式退出。
-
任務棧的缺點:
-
(1) 每開啟一次頁面都會在任務棧中添加一個Activity,而只有任務棧中的Activity全部清除出棧時,任務棧被銷毀,程式才會退出,這樣就造成了用,戶體驗差, 需要點擊多次返回才可以把程式退出了。
-
(2) 每開啟一次頁面都會在任務棧中添加一個Activity還會造成資料冗餘, 重複資料太多, 會導致記憶體溢出的問題(OOM)。
為瞭解決任務棧產生的問題,Android為Activity設計了啟動模式,那麼下面的內容將介紹Android中Activity的啟動模式,這也是最重要的內容之一。
Activity的4種啟動模式
啟動模式(launchMode)在多個Activity跳轉的過程中扮演者重要的角色,它可以解決是否產生新的Activity執行個體,是否重用已經存在的Activity執行個體,是否和其他執行個體共用一個任務棧。任務棧是一個具有站結構的對象,一個任務棧可以管理多個Activity,每啟動一個應用,也就建立一個與之對應的任務棧。
-
Activity一共有以下四種launchMode模式:
-
① standard
-
② singTop
-
③ singTask
-
④ singleInstance
我們可以在AndroidManifest.xml配置<activity>的android:launchMode屬性為以上四種之一即可。
為了詳細講解啟動模式,我們建立一個工程,裡面有兩個Activity,分別是FirstActivity和SecondActivity,啟動模式都是standard。下面是介面和關鍵代碼:
介面一
介面二
FirstActivity檔案:
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); System.out.println("當前任務棧ID:" + getTaskId() + "當前是第一個介面(" + this.toString()+")");}@Overrideprotected void onDestroy() { super.onDestroy(); System.out.println("第一個介面("+this.toString() + ")退出任務棧");}
SecondActivity檔案
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); System.out.println("當前任務棧ID:" + getTaskId() + "當前是第二個介面(" + this.toString()+")");}@Overrideprotected void onDestroy() { super.onDestroy(); System.out.println("第二個介面("+this.toString() + ")退出任務棧");}
-
standard 詳細講解
-
概述:在本模式中,不管有沒有已存在的執行個體,都產生新的執行個體。即每次調用startActivity()啟動時都會建立一個新的Activity放在棧頂,可重複建立。
-
操作:啟動程式後,執行以下操作
①啟用第二個介面 -> 啟用第一個介面 -> 啟用第二個介面 -> 啟用第一個介面 ->啟用第二個介面
②狂按返回鍵
-
列印的Log如下所示:
-
棧中的情況如下所示:
-
每次啟用都會建立新的執行個體,每次返回都會銷毀執行個體並出棧
-
singleTop詳細講解
-
概述:如果任務棧的棧頂存在這個要開啟的activity,不會重新的建立activity,而是複用已經存在的activity。保證棧頂如果存在,不會重複建立。
-
為了講解的更清楚,我在按鈕中加入了如下Log
public void first(View v) { Intent intent = new Intent(this, FirstActivity.class); startActivity(intent); System.out.println("想要啟用第一個頁面");}public void second(View v) { Intent intent = new Intent(this, SecondActivity.class); startActivity(intent); System.out.println("想要啟用第二個頁面");}
-
操作:啟動後執行一下操作
①啟用第二個介面 -> 啟用第一個介面 -> 啟用第一個介面 -> 啟用第一個介面
②按三次返回鍵
-
列印的Log如下所示:
-
棧中的情況如下所示:
-
注意當第一個頁面處於棧頂,並且還想要啟用第一個介面時就會因為singleTop模式不再建立新的執行個體;但如果第一個介面不再棧頂,那麼還是會建立新的執行個體的。
-
singleTask詳細講解
-
概述:在當前任務棧裡面只能有一個執行個體存在;當開啟activity的時候,就去檢查在任務棧裡面是否有執行個體已經存在,如果有執行個體存在就複用這個已經存在的activity,並且把這個activity上面的所有的別的activity都清空,複用這個已經存在的activity。保證整個任務棧裡面只有一個執行個體存在;
-
操作:啟動後執行一下操作
①啟用第一個介面 -> 啟用第二個介面 -> 啟用第二個介面 -> 啟用第一個介面
②按一次返回鍵
-
列印的Log如下所示:
-
這裡的棧結構沒法用圖畫出來了,我就描述一下Log吧。
-
應用開啟,第一條Log打出,然後點擊“啟用第一個介面”,由於棧中已經有執行個體了,所以沒有建立新的執行個體,直接複用。然後點擊“啟用第二個介面”,轉到第二個介面,並建立出執行個體對象,然後在點擊一次“啟用第二個介面”,有建立了一個執行個體對象;此時,點擊“啟用第一個介面”,這時會去檢查任務棧是否有第一個介面的執行個體,發現存在執行個體,直接複用,並把第一個介面棧上面的兩個第二個介面的執行個體直接出棧。
-
最後點擊返回鍵,由於此時棧中只剩下第一個介面的執行個體了,所以就只列印了一次Log。
-
singleInstance詳細講解
-
概述:這種啟動模式比較特殊,因為它會啟用一個新的棧結構,將Activity放置於這個新的棧結構中,並保證不再有其他Activity執行個體進入。
-
操作:啟動後執行一下操作
①啟用第二個介面 -> 啟用第二個介面 -> 啟用第一個介面
②按3次返回鍵
-
列印的Log如下所示:
-
棧中的情況如下所示:
-
正如概述中所說的,應用啟動時,由於給第一個介面配置的singleInstance模式,所以直接建立了一個新的任務棧給第一個Activity,並保證不會有其他Activity入棧,並且還保證了執行個體的複用。然後去啟用第二個Activity,由於第二個介面是標準模式,所以直接建立了新執行個體、併入棧。
Android基礎筆記(八)- Activity生命週期與任務棧