Android四大組件之Activity

有關Activity介紹的文字實在是太多了,本著對Android開發(fā)基礎知識進行查漏補缺的原則,還是將這部分的知識梳理成了這篇文章。

Activity作為Android中最為重要的組件,在漢語中似乎一直沒有合適的詞語表達。Activity是“界面展示”+“后臺邏輯”的結合,用“活動”一詞對這一組件進行描述實在是太牽強啦。因此,本文仍然使用Activity來指代這一組件吧。本文從生命周期和啟動模式兩個部分總結了Activity相關的知識點。


一、 Activity的生命周期

都閃開,首先還是官方文檔中那張熟悉得不能再熟悉的生命周期流程圖:


雖然圖中未列出,Activity在與用戶進行交互的過程中,在如下四種狀態(tài)之間互相切換:

Running: Activity正處于Activity棧最頂端,與用戶正在進行交互。(完全可見)

Paused:與Running狀態(tài)不同,Activity此時未完全顯示出來,例如被一個dialog或者透明的Activity所部分遮蓋,無法與用戶交互,但仍然保持著狀態(tài)信息數(shù)據(jù)。(部分可見)

Stopped:當Activity被其他Activity完全覆蓋不可見,此時不再處于Activity棧頂端。(完全不可見)

Destroyed:當Activity被系統(tǒng)回收或者被用戶關閉,則會被系統(tǒng)銷毀掉。

如圖所示在這四種狀態(tài)的切換過程中,系統(tǒng)將會回調不同的方法:

onCreate():該方法在Activity第一次被創(chuàng)建的時候被回調,我們通常在該方法中進行一些靜態(tài)初始化工作,例如加載頁面布局,創(chuàng)建View,綁定數(shù)據(jù)等等。

onStart():在Activity被啟動或重新啟動過程中會調用該方法。

onResume():在Activity能夠與用戶交互之前調用此方法。我們通常會在該方法中初始化并打開一些獨占設備,例如相機,重新初始化在onPause方法中釋放的資源等。

onPause():當系統(tǒng)開始調用其他Activity時會回調此方法。我們通常會在其中釋放那些在onResume中打開的資源,確認對持久性數(shù)據(jù)的未保存更改、停止動畫、釋放sensor,reciever,ContentProvider保存數(shù)據(jù),以及其他可能消耗 CPU 的內(nèi)容。需要注意的是這里進行的操作不能太耗時,因為它返回后,下一個 Activity 才能繼續(xù)執(zhí)行。該方法與onResume方法相對應,這兩對方法從Activity是否可交互的角度來回調的。

onStop():當系統(tǒng)要停止或覆蓋該Activity時會回調此方法,此時Activity已經(jīng)不可見了,該方法與onStart方法相對應,這兩對方法是從Activity是否可見的角度來回調的。

onRestart():當Activity未被完全銷毀掉,需要重新啟動該Activity時候將會在onStop和onStart方法之間回調該方法。

onDestroy():當系統(tǒng)要銷毀掉Activity前會調用該方法。無論是Activity是人為finish掉還是系統(tǒng)由于資源短缺而回收,都會回調該方法。這里可以進行一些資源釋放和回收工作。

上述方法的回調順序都是在Activity處于正常的生命周期內(nèi),而當Activity配置發(fā)生改變或系統(tǒng)資源緊張對Activity進行了回收時,Activity則會被銷毀,抑或重新創(chuàng)建。為了應對Activity非正常生命周期內(nèi)的情況,系統(tǒng)使用了onSaveInstanceState和onRestoreInstanceState兩對方法來完成對Activity狀態(tài)信息和數(shù)據(jù)的存儲和恢復。這對方法在Activity正常的生命周期中是不會被調用的,只有當資源不足或配置改變而導致的異常銷毀重建時才會調用。

在這兩個方法中,系統(tǒng)自動做了一定的存儲和恢復工作,我們也可以將我們需要保存的數(shù)據(jù)存于Bundle中,從而保證我們Activity的強壯性。


二、 Activity的任務棧和啟動模式

Android系統(tǒng)采用了棧結構來組織和存儲Activity實例對象集合,這樣的棧結構被稱為任務棧(Task Stack)。一個任務棧中的Activity可以來自不同的App,而同一個App的不同Activity也可以存在于不同的任務棧中。棧結構采用FIFO的組織模式,當前正與用戶交互的Activity位于棧頂,該任務棧也位于前臺。

為了滿足開發(fā)中的各種特殊需求,Activity可以采用四種模式完成啟動:

standard 默認的啟動模式。每次都要新創(chuàng)建Activity的實例對象,然后進入原Activity所在的的任務棧,覆蓋在原Activity之上。(在這種啟動模式下,哪個Activity啟動了新的Activity,那么這個新的Activity就運行在哪個Activity所在任務棧中。)

singleTop 棧頂復用模式。在這種啟動模式下,如果當前任務棧頂?shù)腁ctivity與要啟動的Activity相同,則不創(chuàng)建新的的Activity對象(自然也不會回調生命周期中的方法),而是復用當前棧頂?shù)腁ctivity對象,但仍然會調用onNewIntent()方法。如果棧頂Activity與要啟動的Activity不同,則創(chuàng)建新的Activity實例對象,并入棧。這種啟動模式通常用于接收消息點擊后所顯示的Activity。

singleTask 棧內(nèi)復用。在這種啟動模式下,系統(tǒng)首先判斷當前任務棧中是否存在要啟動的Activity實例對象。如果當前棧中已經(jīng)存在該Activity實例對象,則覆蓋在該Activity實例對象之上的Activity都要出棧并銷毀,從而復用已經(jīng)存在的Activity對象,但仍然會調用onNewIntent()方法。使用該模式時請注意Activity所要運行的任務棧,該模式具有創(chuàng)建不存在的任務棧的作用。

另外有一點需要注意的是,當所啟動的Activity實例對象并未位于當前任務棧,而是位于后臺任務棧中,則該后臺任務棧中的Activity實例對象都被切換到前臺任務棧中,并仍按原棧中順序組織和存儲。

singleInstance 單例模式。使用該模式啟動的Activity,系統(tǒng)為該Activity新建一個任務棧來運行,從而可以滿足多個應用共享該Activity實例的需求。

在Activity實例對象的創(chuàng)建和啟動過程中,系統(tǒng)必然要通過某種方式指定是所啟動的Activity實例對象,以及該對象所屬的任務棧。通常情況下,Activity? A所啟動了Activity B,如無特殊指定,系統(tǒng)會將B運行于A所屬的任務棧中。

Android系統(tǒng)使用TaskAffinity參數(shù)標識了該Activity對象期望所屬的任務棧(默認為該app的包名),僅僅是期望,而不是一定要運行在該任務棧中,如果該任務棧還不存在,未必會創(chuàng)建該任務棧(singleTask和singleInstance模式會創(chuàng)建)。singleTask這種棧內(nèi)復用模式就是在TaskAffinity所指定的棧內(nèi)進行復用。TaskAffinity參數(shù)通常與allowTaskReparenting結合使用。

我們可以通過manifest文件和Intent Flag兩種方式來指定Activity的啟動模式,前者的優(yōu)先級低于后者。常用的Intent Flag包括以下幾種方式:

Intent.FLAG_ACTIVITY_NEW_TASK:新創(chuàng)建一個任務棧來運行Activity,通常用于service啟動Activity的場景。

Intent.FLAG_ACTIVITY_SINGLE_TOP:以singleTop模式啟動Activity。

Intent.FLAG_ACTIVITY_CLEAR_TOP:通常與Intent.FLAG_ACTIVITY_NEW_TASK相結合使用,達到singleTask模式的效果。

Intent.FLAG_ACTIVITY_NO_HISTORY:以該模式啟動的Activity,當該Activity啟動其他Activity后就會被銷毀掉,不存儲于任務棧中。

另外,我們還可以在manifest文件中指定clearTaskOnLaunch屬性,保證每次返回該Activity時,其上的Activity都被清除掉,從而保證該Task每次初始化時都只有這個一個Activity。


Note:

良好的編程習慣:在你負責開發(fā)的activity中加入啟動該activity的方法。


參考書目:

?Android官方文檔

《Android群英傳》 作者:徐宜生

《Android開發(fā)藝術探索》 作者:任玉剛

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容