Android的啟動模式(上)

Mz_Chris發表於2015-08-27

Android的啟動模式(上)

1. 基本介紹

大家平時只要懂一點Android知識的話,都一定會知道,一個應用的組成,往往包含了許多的activity元件,每個activity都應該圍繞使用者的特定動作進行跳轉設計。比如說,一個電話通訊錄的應用可能有一個總體展示電話錄上所有儲存的姓名的activity,當使用者選擇指定的姓名時,可以啟動另一個新的activity用來展示選中此姓名的詳細內容。當然,一個activity也可以用來開啟同一臺手機但存在在其它應用的activity,比如,你的應用想要傳送一份郵件時,可以定義一個intent來執行一個"send"動作幷包含一個資料(地址和資訊),另一個應用中此時有一個剛好可以處理這種intent的activity就會被開啟(如果有多個activity支援同樣的intent,那麼系統就會讓使用者自行選擇一個)。當email被髮送後,你的activity被恢復並且看起來傳送郵件的activity好像是你應用的一部分。即使兩個activity來自不同的應用,Android系統也能將兩個activity儲存在同一個任務中來實現這種無縫隙的使用者體驗。這裡,我們就引出了一個概念,究竟何為Android中的任務Tasks?它與啟動模式又有什麼關係?所謂的Back Stack又是什麼?在本篇中,我主要分享一下Tasks與Back Stack的基本介紹,為之後介紹android的啟動模式做一下鋪墊。當然,若你想詳細瞭解此內容,也可以訪問官方文件:Task and Back Stack

2. Tasks與Back Stack

一般說來,Tasks是我們在執行某種工作時所互動的activity的集合,這些activity集合按照開啟的順序被放置在同一個棧中,這個棧叫作Back Stack(我稱為後退棧)。當我們點選到launcher上的圖示時,這個圖示對應的應用的task則會被置換到前臺。若這個應用不存在task,也說明沒有開啟過或者開啟過但被銷燬了,那麼就會為這個應用建立一個新的task,此時這個應用的MainActivity則會被建立,然後作為根Activity被壓入到這個task中。

噹噹前的Activity啟動了另外一個activity之後,新的activity就會被壓入棧頂,並擁有焦點。之前的activity仍然儲存在棧中,但是狀態是停止的。當activity處於棧中的時候,系統會保留當前介面的狀態,當使用者按下back鍵時,當前就activity就會從stack中彈出銷燬,之前的一個activity就會從儲存的狀態中恢復。在棧中的順序不能被重新安排,只允許在棧上執行壓入和彈出。當建立新的activity的時候,壓入棧中;當按下後退鍵的時候,彈出棧中。因此,後退棧是一個“後進先出”的結構體。如下圖:

back_stack

當然,如果我們不停的按後退鍵,棧中的activity會不停的被彈出,直到回到home介面(或者回到建立task的正在執行的activity)。當所有的activity都從棧中移除之後,這個task就被銷燬了。

task可以被整體移到後臺,當使用者啟動了一個新的task,或者按下了home按鈕。後臺task中的所有activity的狀態都是停止的,task的stack中的內容被儲存下來,只是task失去了焦點。

我們需要注意的是:後臺可以保持多個Task同時存在,但是,若在同一時刻後臺執行了太多的Task,這時系統要能會銷燬後臺的Activity,以用來回收記憶體,這會導致activity狀態的丟失。

3. 儲存Activity的狀態

按照前面所說的,當Activity停止時(Stopped)時,系統預設會儲存其狀態。當我們通過back鍵回到這個Activity時就會恢復離開時候的介面。當然,當多個Tasks同時儲存在後臺時,系統也有可能會銷燬後臺的activity,以回收記憶體。在這種情況下,系統仍然會知道Activity在task中的位置,當通過back鍵回到這個Activity時,系統會重新建立(recreate)一個Activity,而不是像之前一樣恢復(resume)它,因此,為了不丟失Activity的內容,我們可以通過實現onSaveInstanceState()方法來主動儲存資料。

4. 總結

通過上面對Task與back stack的學習,相信對於一些概念有了更加清楚的認識,現在我們可以總結一下:

  • activity A 啟動activity B,activity A 停止,但是系統還是保留著它的狀態。當使用者在activity B上按下後退按鍵,activity A會從保留的狀態中的恢復執行。

  • 當使用者按下home鍵後離開一個task,這個task的當前activity停止,整個task進入到後臺。系統保留著stack中的每一個activity的狀態。如果使用者點選launcher上的task圖示,這個task就會被重新放到前臺,task的棧頂activity也會恢復執行。

  • 當使用者按下後退按鈕,棧頂的activity就會從棧中彈出銷燬,之前的activity就會恢復執行。activity被銷燬後,系統不會保持它的狀態。

  • 有的activity可以被例項化多次,甚至是從不同的task。

  • 當後臺中有同時存在多個Task時,系統可能會銷燬儲存在後臺的activity以回收記憶體,為了不丟失activity中內容,我們可通過onSaveInstanceState()方法儲存資料。

Android系統管理Task,是通過將所有的activity按照啟動的順序壓入到一個Task中,若一個Activity被啟動多次,會預設建立它的多個例項,然後將新的例項壓入。當然,我們也可以打破這種預設的行為。可能你想在你應用的activity啟動時開始一個新的任務(而不是放置到當前棧中);或者,當你啟動一個activity,你想把已經執行的它的一個例項提到前臺來(而不是建立一個新的例項放在後退棧的頂端);或者,你希望當使用者離開任務時,你的後退棧清除除了根activity以外所有的activity。對於這些行為,我們該如何進行設定?

好了,今天的分享就到這裡,接下來我會針對上面的問題分享Android的啟動模式,希望大家持續關注!

相關文章