Task是一個Activity的集合為了能夠正確完成工作的集合,上述就是一個例子,而back stack(或只簡稱stack) 就是放置這些Activity並且排列的地方。在按下程式的launcher icon後(不管是按下Home鍵後點選桌面捷徑,還是點擊程式列表中的icon),Android會查看在Task群中是否有該App所建立的Task,如果有,則會將該Task帶到foreground,並啟動Foreground Activity與回復其狀態,而其他的Task則會到background,如果Task中並沒有該App所建立的Task,則會重新建立一個新的Task,並啟動該程式的Main Activity。
而Back Stack的存放過程如下圖,一開始就只有Activity 1,所以建立起新Task,並將Activity 1放Back Stack中,而當該Activity 1啟動Activity 2後,Activity 1便進入Pause,Activity 2則放到Back Stack的前面,並且為Foreground Activity,如果Activity 2再啟動Activity 3,則會進行一樣的動作,Activity 3便成為Foreground Activity,其餘皆進入Pause狀態,如果這時Activity 3按下上一頁鈕,則Activity 3被Destroy,接著Activity 2便成Foreground Activity並回覆狀態,如果到最後Activity 1也被Destroy,則該Task和Back Stack就不再存在。Back Stack有兩個重要的特性便是:先進後出及不被重新排序整理,也就是進來的順序是固定,不會更改。
有以上概念可以得知,在不同的Task其實會放置相同的Activity在Back Stack中,例如:兩個不同Task的Activity都呼叫相同發送Email的Activity,則這兩個Back Stack都會存放啟動相同的Activity狀態,也就是發送Email的Activity會被啟動多次,並存放到不同的Back Stack。
Activity會在進入Background(排入Back Stage)或者因為記憶體不足,而Android自動將App的Process刪除,以取得更多的記憶體時,會呼叫onSaveInstanceState(Bundle outState)進行狀態的儲存,但是這個事件並不一定會呼叫,例如:按上一頁要Destroy Activity時,所以也就是為何Activity從Back Stage回到Foreground時,之前Activity的狀態仍會存在,所以如果有額外的資訊想要保留,以便能夠讓Activity re-initial後回復或使用所儲存的資訊,則可以Override onSaveInstanceState(Bundle outState)進行改寫,將所欲保留的資訊進行儲存的動作,但是如果要儲存持續性的資料,不建議寫在onSaveInstanceState(Bundle outState),而可以在onPause()寫入持續性的資料。
上述說明如果要使用額外儲存在onSaveInstanceState(Bundle outState)的資料,必須是Activity re-initial時,是因為只有在re-initial時才會重新執行onCreate(Bundle savedInstanceState)或者執行onRestoreInstanceState(Bundle savedInstanceState),而這些所帶入的Bundle就是onSaveInstanceState(Bundle outState)所使用的Bundle,會re-initial的情況有翻轉螢幕,或因為記憶體不足Android自動將App的Process刪除,而導致使用者回到Activity時發生等情況。
如果不要畫面翻轉時讓Activity re-initial,則可以在AndroidManifest.xml設定Acitivity的configChanges屬性,例如:android:configChanges="keyboardHidden|orientation|screenSize",此時便不會re-initial,而會執行onConfigurationChanged(Configuration newConfig)。
轉貼請註明出處,最好直接使用聯結轉貼!Thanks~
作者: Samuel - 林靖傑
日期:2013/04/18