Android下Activity的啟動(dòng)模式,涉及到了Task和BackStack的內(nèi)容,對(duì)這些不熟悉的朋友,可以先去看看:Android--Activity的啟動(dòng)模式。這篇博客主要講講Task和BackStack的高級(jí)內(nèi)容。
本篇文章的內(nèi)容包括:
開始一個(gè)Task
BackStack回退時(shí)Activity狀態(tài)
BackStack的清理
開始一個(gè)Task
之前已經(jīng)了解到,Android的Task通常起始于HOME頁面下點(diǎn)擊應(yīng)用程序圖標(biāo)或其在桌面快捷圖標(biāo)。所以我們?cè)陂_發(fā)一個(gè)應(yīng)用程序的時(shí)候,需要指定應(yīng)用程序的入口Activity,通過在AndroidManifest.xml清單文件中某個(gè)<Activity/>標(biāo)簽內(nèi),使用<intent-filter/>標(biāo)簽內(nèi)指定。需要設(shè)置action為"android.intent.action.MAIN",設(shè)置category為"android.intent.category.LAUNCHER"。
1 <activity ... > 2 <intent-filter ... > 3 <action android:name="android.intent.action.MAIN" /> 4 <category android:name="android.intent.category.LAUNCHER" /> 5 </intent-filter> 6 ... 7 </activity>
這樣,當(dāng)用戶點(diǎn)擊應(yīng)用程序圖標(biāo)之后,就會(huì)以這個(gè)入口Activity為基礎(chǔ),創(chuàng)建一個(gè)任務(wù)(Task),而這個(gè)Activity為這個(gè)Task中的第一個(gè)Activity,稱為根Activity。
BackStack回退時(shí)Activity狀態(tài)
Android中存在多個(gè)Task,但是同一時(shí)刻只有一個(gè)Task被置于前臺(tái),其它的均為后臺(tái),而后臺(tái)的Task內(nèi)的Activity,均為Stopped狀態(tài)。Android系統(tǒng)中有多種方式切換Task,比如:按HOME鍵回到桌面、長(zhǎng)按HOME鍵切換到其他Task等。而在同一個(gè)Task中,也只有BackStack最上面的Activity處于獲得焦點(diǎn)的狀態(tài),其它也為Stopped,每當(dāng)系統(tǒng)需要把Activity置于Stopped時(shí),都會(huì)自動(dòng)保其狀態(tài)數(shù)據(jù),比如:控件輸入值、滾動(dòng)條位置,以便下次獲得焦點(diǎn)的時(shí)候還原。
但是有一種特殊的情況,對(duì)Android系統(tǒng)的內(nèi)存管理有了解的朋友都應(yīng)該知道,當(dāng)系統(tǒng)資源不足的時(shí)候,如內(nèi)存不足,會(huì)自動(dòng)回收一些優(yōu)先級(jí)比較低的組件的線程,以釋放資源給新的組件使用。那么就存在問題了,當(dāng)一個(gè)Task被切換到后臺(tái)之后,如果系統(tǒng)資源告急,自動(dòng)銷毀了某個(gè)后臺(tái)Task中的Activity(除了根Activity外),當(dāng)用戶再次切換回那個(gè)Task的時(shí)候,BackStack中存在這個(gè)Activity的標(biāo)記,但是內(nèi)存中已經(jīng)不存在這個(gè)Activity的實(shí)例了,這個(gè)時(shí)候,系統(tǒng)就會(huì)通過Bundle來重新創(chuàng)建一個(gè)Activity用于還原它,這樣保證了用戶體驗(yàn),使用戶還是感覺在之前的頁面中操作。但是默認(rèn)情況下,Bundle是不會(huì)保存之前Activity中的信息的,比如:控件輸入值、滾動(dòng)條位置。這個(gè)時(shí)候,如果這個(gè)Activity的內(nèi)容很重要的話,需要我們以編碼的方式去保存數(shù)據(jù),并在重新創(chuàng)建的時(shí)候,以編碼的方式還原這個(gè)數(shù)據(jù)。
這個(gè)時(shí)候就需要用到兩個(gè)Activity的生命周期方法,onSaveInstanceState()和onRestoreInstanceState()。下面是這兩個(gè)方法的簽名:
protected void onSaveInstanceState(Bundle outState):當(dāng)Activity被系統(tǒng)回收的時(shí)候被調(diào)用 ,用這個(gè)方法保存Activity中需要保存的數(shù)據(jù),存入outState參數(shù)即可。
protected void onRestoreInstanceState(Bundle savedInstanceState):當(dāng)Activity被系統(tǒng)恢復(fù)的時(shí)候被調(diào)用,從Bundle中取出數(shù)據(jù),設(shè)置會(huì)控件中,當(dāng)然也可以通過重寫onCreate()方法來設(shè)置數(shù)據(jù),因?yàn)閛nCreate()一樣可以獲取到,但是推薦使用onRestoreInstanceState()。
BackStack的清理
上面描述的Activity被系統(tǒng)回收已經(jīng)之后在還原的情況,為默認(rèn)情況。在Android系統(tǒng)的清單文件中,不光為我們提供了設(shè)置啟動(dòng)模式的屬性android:LauncherMode,還為我們提供了Activity的清理模式,有如下幾個(gè):
android:alwaysRetainTaskState:這個(gè)屬性只對(duì)根Activity有效,默認(rèn)為false,當(dāng)其設(shè)置為true的時(shí)候,當(dāng)這個(gè)根Activity失去焦點(diǎn)被置于后臺(tái)的時(shí)候,如不出現(xiàn)意外情況,其中的Activity將不會(huì)被系統(tǒng)回收。
android:clearTaskOnTask:這個(gè)屬性只對(duì)根Activity有效,當(dāng)這個(gè)根Activity失去焦點(diǎn)被置于后臺(tái)的時(shí)候,會(huì)清理BackStack中根Activity之上的所有Activity,并在下次獲得焦點(diǎn)的時(shí)候顯示根Activity。
android:finishOnTaskLaunch:這個(gè)屬性只應(yīng)用于單個(gè)Activity,它默認(rèn)為false,當(dāng)其設(shè)置為true的時(shí)候,當(dāng)前Task如果在這個(gè)Activity獲得焦點(diǎn)的時(shí)候被切換到后臺(tái),那么這個(gè)Activity直接被銷毀,哪怕只是離開一小會(huì)兒。
總結(jié)
自此就把Task和BackTask的內(nèi)容介紹完了,把Task和BackStack理解透徹了,對(duì)android應(yīng)用開發(fā)有非常好的作用。可以有效提高用戶體驗(yàn),應(yīng)用中的Activity應(yīng)該如何顯示,應(yīng)該長(zhǎng)存(singleInstance),還是應(yīng)該閱后即焚(finishOnTaskLaunch),等等場(chǎng)景。一款應(yīng)用不應(yīng)僅僅是功能的實(shí)現(xiàn),還需要注重用戶體驗(yàn),它不僅僅是一款應(yīng)用,而是應(yīng)該把它當(dāng)成一款產(chǎn)品來開發(fā)。
Android 多線程-----AsyncTask詳解