activity生命周期詳解,大牛教會你

Activity和BroadcastReceiver ,Service ,contentprovider 並稱為Android 四大組件,對於他們來說構成了Android應用的骨架,缺一不可,對於Activity來說,更是他們之中的重中之重。

首先學習Activity,需要先了解一下他的作用:

在日常應用中Activity是與用戶交互的接口,它提供了一個用戶完成相關操作的窗口。當我們在開發中創建Activity後,通過調用setContentView(View)方法來給該Activity指定一個佈局界面,而這個界面就是提供給用戶交互的接口。Android系統中是通過Activity棧的方式來管理Activity的,而Activity自身則是通過生命週期的方法來管理的自己的創建與銷燬,既然如此,現在我們就來看看Activity生命週期是如何運作的。

其次對於Activity來說是有一個運行狀態的,就好比當我們的頁面處於屏幕的最前端,處於陰影狀態,處於後臺中等等又可細分為好幾種狀態:

Active/Running:

Activity處於活動狀態,此時Activity處於棧頂,是可見狀態,可與用戶進行交互。

Paused:

當Activity失去焦點時,或被一個新的非全屏的Activity,或被一個透明的Activity放置在棧頂時,Activity就轉化為Paused狀態。但我們需要明白,此時Activity只是失去了與用戶交互的能力,其所有的狀態信息及其成員變量都還存在,只有在系統內存緊張的情況下,才有可能被系統回收掉。

Stopped:

當一個Activity被另一個Activity完全覆蓋時,被覆蓋的Activity就會進入Stopped狀態,此時它不再可見,但是跟Paused狀態一樣保持著其所有狀態信息及其成員變量。

Killed:

當Activity被系統回收掉時,Activity就處於Killed狀態。

Activity會在以上四種形態中相互切換,至於如何切換,這因用戶的操作不同而異。

瞭解了Activity的4種形態後,我們就來聊聊Activity的生命週期。

activity生命週期詳解,大牛教會你

相信大部分人對這種流程圖並不陌生,嗯,我們下面主要聊得話題就是圍繞這張流程圖了。我們先有個大概印象,後面我們分析完後再回來看,就相當清晰了。

所謂的典型的生命週期就是在有用戶參與的情況下,Activity經歷從創建,運行,停止,銷燬等正常的生命週期過程。我們這裡先來介紹一下幾個主要方法的調用時機,然後再通過代碼層面來驗證其調用流程。

onCreate : 該方法是在Activity被創建時回調,它是生命週期第一個調用的方法,我們在創建Activity時一般都需要重寫該方法,然後在該方法中做一些初始化的操作,如通過setContentView設置界面佈局的資源,初始化所需要的組件信息等。

onStart : 此方法被回調時表示Activity正在啟動,此時Activity已處於可見狀態,只是還沒有在前臺顯示,因此無法與用戶進行交互。可以簡單理解為Activity已顯示而我們無法看見擺了。

onResume : 當此方法回調時,則說明Activity已在前臺可見,可與用戶交互了(處於前面所說的Active/Running形態),onResume方法與onStart的相同點是兩者都表示Activity可見,只不過onStart回調時Activity還是後臺無法與用戶交互,而onResume則已顯示在前臺,可與用戶交互。當然從流程圖,我們也可以看出當Activity停止後(onPause方法和onStop方法被調用),重新回到前臺時也會調用onResume方法,因此我們也可以在onResume方法中初始化一些資源,比如重新初始化在onPause或者onStop方法中釋放的資源。

onPause : 此方法被回調時則表示Activity正在停止(Paused形態),一般情況下onStop方法會緊接著被回調。但通過流程圖我們還可以看到一種情況是onPause方法執行後直接執行了onResume方法,這屬於比較極端的現象了,這可能是用戶操作使當前Activity退居後臺後又迅速地再回到到當前的Activity,此時onResume方法就會被回調。當然,在onPause方法中我們可以做一些數據存儲或者動畫停止或者資源回收的操作,但是不能太耗時,因為這可能會影響到新的Activity的顯示——onPause方法執行完成後,新Activity的onResume方法才會被執行。

onStop : 一般在onPause方法執行完成直接執行,表示Activity即將停止或者完全被覆蓋(Stopped形態),此時Activity不可見,僅在後臺運行。同樣地,在onStop方法可以做一些資源釋放的操作(不能太耗時)。

onRestart :表示Activity正在重新啟動,當Activity由不可見變為可見狀態時,該方法被回調。這種情況一般是用戶打開了一個新的Activity時,當前的Activity就會被暫停(onPause和onStop被執行了),接著又回到當前Activity頁面時,onRestart方法就會被回調。

onDestroy :此時Activity正在被銷燬,也是生命週期最後一個執行的方法,一般我們可以在此方法中做一些回收工作和最終的資源釋放。

下面我們通過程序來驗證上面流程中的幾種比較重要的情況,同時觀察生命週期方法的回調時機。

說完生命週期,現在我們在來說說加載模式

Standard:

默認模式,可以不用寫配置。在這個模式下,都會默認創建一個新的實例。因此,在這種模式下,可以有多個相同的實例,也允許多個相同Activity疊加。

例如:

若我有一個Activity名為A1, 上面有一個按鈕可跳轉到A1。那麼如果我點擊按鈕,便會新啟一個Activity A1疊在剛才的A1之上,再點擊,又會再新啟一個在它之上……

點back鍵會依照棧順序依次退出。

singleTop

可以有多個實例,但是不允許多個相同Activity疊加。即,如果Activity在棧頂的時候,啟動相同的Activity,不會創建新的實例,而會調用其onNewIntent方法。

例如:

若我有兩個Activity名為B1,B2,兩個Activity內容功能完全相同,都有兩個按鈕可以跳到B1或者B2,唯一不同的是B1為standard,B2為singleTop。

若我意圖打開的順序為B1->B2->B2,則實際打開的順序為B1->B2(後一次意圖打開B2,實際只調用了前一個的onNewIntent方法)

若我意圖打開的順序為B1->B2->B1->B2,則實際打開的順序與意圖的一致,為B1->B2->B1->B2。

singleTask

只有一個實例。在同一個應用程序中啟動他的時候,若Activity不存在,則會在當前task創建一個新的實例,若存在,則會把task中在其之上的其它Activity destory掉並調用它的onNewIntent方法。

如果是在別的應用程序中啟動它,則會新建一個task,並在該task中啟動這個Activity,singleTask允許別的Activity與其在一個task中共存,也就是說,如果我在這個singleTask的實例中再打開新的Activity,這個新的Activity還是會在singleTask的實例的task中。

例如:

若我的應用程序中有三個Activity,C1,C2,C3,三個Activity可互相啟動,其中C2為singleTask模式,那麼,無論我在這個程序中如何點擊啟動,如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在多個實例,但是C2只會存在一個,並且這三個Activity都在同一個task裡面。

但是C1->C2->C3->C2->C3->C1-C2,這樣的操作過程實際應該是如下這樣的,因為singleTask會把task中在其之上的其它Activity destory掉。

操作:C1->C2 C1->C2->C3 C1->C2->C3->C2 C1->C2->C3->C2->C3->C1 C1->C2->C3->C2->C3->C1-C2

實際:C1->C2 C1->C2->C3 C1->C2 C1->C2->C3->C1 C1->C2

若是別的應用程序打開C2,則會新啟一個task。

如別的應用Other中有一個activity,taskId為200,從它打開C2,則C2的taskIdI不會為200,例如C2的taskId為201,那麼再從C2打開C1、C3,則C2、C3的taskId仍為201。

注意:如果此時你點擊home,然後再打開Other,發現這時顯示的肯定會是Other應用中的內容,而不會是我們應用中的C1 C2 C3中的其中一個。

singleInstance

只有一個實例,並且這個實例獨立運行在一個task中,這個task只有這個實例,不允許有別的Activity存在。

例如:

程序有三個ActivityD1,D2,D3,三個Activity可互相啟動,其中D2為singleInstance模式。那麼程序從D1開始運行,假設D1的taskId為200,那麼從D1啟動D2時,D2會新啟動一個task,即D2與D1不在一個task中運行。假設D2的taskId為201,再從D2啟動D3時,D3的taskId為200,也就是說它被壓到了D1啟動的任務棧中。

若是在別的應用程序打開D2,假設Other的taskId為200,打開D2,D2會新建一個task運行,假設它的taskId為201,那麼如果這時再從D2啟動D1或者D3,則又會再創建一個task,因此,若操作步驟為other->D2->D1,這過程就涉及到了3個task了。


分享到:


相關文章: