活動(Activity)詳解

一:活動狀態

每個活動在其生命週期中最多可能會有四種狀態。
1. 運行狀態
當一個活動位於返回棧的棧頂時,這時活動就處於運行狀態。系統最不願意回收的就是處於運行狀態的活動,因爲這會帶來非常差的用戶體驗。
2. 暫停狀態
當一個活動不再處於棧頂位置,但仍然可見時,這時活動就進入了暫停狀態。你可能會覺得既然活動已經不在棧頂了,還怎麼會可見呢?這是因爲並不是每一個活動都會佔滿整個屏幕的,比如對話框形式的活動只會佔用屏幕中間的部分區域,你很快就會在後面看到這種活動。處於暫停狀態的活動仍然是完全存活着的,系統也不願意去回收這種活動(因爲它還是可見的,回收可見的東西都會在用戶體驗方面有不好的影響),只有在內存極低的情況下,系統纔會去考慮回收這種活動。
3. 停止狀態
當一個活動不再處於棧頂位置,並且完全不可見的時候,就進入了停止狀態。系統仍然會爲這種活動保存相應的狀態和成員變量,但是這並不是完全可靠的,當其他地方需要內存時,處於停止狀態的活動有可能會被系統回收。
4. 銷燬狀態
當一個活動從返回棧中移除後就變成了銷燬狀態。系統會最傾向於回收處於這種狀態的活動,從而保證手機的內存充足



二:活動的生存期

Activity類中定義了七個回調方法,覆蓋了活動生命週期的每一個環節,下面我來一一介紹下這七個方法。
1. onCreate()
這個方法你已經看到過很多次了,每個活動中我們都重寫了這個方法,它會在活動第一次被創建的時候調用。你應該在這個方法中完成活動的初始化操作,比如說加載佈局、綁定事件等。
2. onStart()
這個方法在活動由不可見變爲可見的時候調用。
3. onResume()
這個方法在活動準備好和用戶進行交互的時候調用。此時的活動一定位於返回棧的棧頂,並且處於運行狀態。
4. onPause()
這個方法在系統準備去啓動或者恢復另一個活動的時候調用。我們通常會在這個方法中將一些消耗CPU的資源釋放掉,以及保存一些關鍵數據,但這個方法的執行速度一定要快,不然會影響到新的棧頂活動的使用。
5. onStop()
這個方法在活動完全不可見的時候調用。它和onPause()方法的主要區別在於,如果啓動的新活動是一個對話框式的活動,那麼onPause()方法會得到執行,而onStop()方法並不會執行。
6. onDestroy()
這個方法在活動被銷燬之前調用,之後活動的狀態將變爲銷燬狀態。
7. onRestart()
這個方法在活動由停止狀態變爲運行狀態之前調用,也就是活動被重新啓動了。
以上七個方法中除了onRestart()方法,其他都是兩兩相對的,從而又可以將活動分爲三種生存期。
1. 完整生存期
活動在onCreate()方法和onDestroy()方法之間所經歷的,就是完整生存期。一般情況下,一個活動會在onCreate()方法中完成各種初始化操作,而在onDestroy()方法中完成釋放內存的操作。
2. 可見生存期
活動在onStart()方法和onStop()方法之間所經歷的,就是可見生存期。在可見生存期內,活動對於用戶總是可見的,即便有可能無法和用戶進行交互。我們可以通過這兩個方法,合理地管理那些對用戶可見的資源。比如在onStart()方法中對資源進行加載,而在onStop()方法中對資源進行釋放,從而保證處於停止狀態的活動不會佔用過多內存。
3. 前臺生存期
活動在onResume()方法和onPause()方法之間所經歷的,就是前臺生存期。在前臺生存期內,活動總是處於運行狀態的,此時的活動是可以和用戶進行相互的,我們平時看到和接觸最多的也這個狀態下的活動。
爲了幫助你能夠更好的理解,Android官方提供了一張活動生命週期的示意圖,如圖2.20所示。


三:活動的啓動模式

活動的啓動模式對你來說應該是個全新的概念,在實際項目中我們應該根據特定的需求爲每個活動指定恰當的啓動模式。啓動模式一共有四種,分別是standardsingleTopsingleTasksingleInstance,可以在AndroidManifest.xml中通過給<activity>標籤指定android:launchMode屬性來選擇啓動模式。
1.standard
standard是活動默認的啓動模式,在不進行顯式指定的情況下,所有活動都會自動使用這種啓動模式。因此,到目前爲止我們寫過的所有活動都是使用的standard模式。經過上一節的學習,你已經知道了Android是使用返回棧來管理活動的,在standard模式(即默認情況)下,每當啓動一個新的活動,它就會在返回棧中入棧,並處於棧頂的位置。對於使用standard模式的活動,系統不會在乎這個活動是否已經在返回棧中存在,每次啓動都會創建該活動的一個新的實例。

2.singleTop
可能在有些情況下,你會覺得standard模式不太合理。活動明明已經在棧頂了,爲什麼再次啓動的時候還要創建一個新的活動實例呢?彆着急,這只是系統默認的一種啓動模式而已,你完全可以根據自己的需要進行修改,比如說使用singleTop模式。當活動的啓動模式指定爲singleTop,在啓動活動時如果發現返回棧的棧頂已經是該活動,則認爲可以直接使用它,不會再創建新的活動實例。

3.singleTask
使用singleTop模式可以很好地解決重複創建棧頂活動的問題,但是正如你在上一節所看到的,如果該活動並沒有處於棧頂的位置,還是可能會創建多個活動實例的。那麼有沒有什麼辦法可以讓某個活動在整個應用程序的上下文中只存在一個實例呢?這就要藉助singleTask模式來實現了。當活動的啓動模式指定爲singleTask,每次啓動該活動時系統首先會在返回棧中檢查是否存在該活動的實例,如果發現已經存在則直接使用該實例,並把在這個活動之上的所有活動統統出棧,如果沒有發現就會創建一個新的活動實例。

4.singleInstance
singleInstance模式應該算是四種啓動模式中最特殊也最複雜的一個了,你也需要多花點功夫來理解這個模式。不同於以上三種啓動模式,指定爲singleInstance模式的活動會啓用一個新的返回棧來管理這個活動(其實如果singleTask模式指定了不同的taskAffinity,也會啓動一個新的返回棧)。那麼這樣做有什麼意義呢?想象以下場景,假設我們的程序中有一個活動是允許其他程序調用的,如果我們想實現其他程序和我們的程序可以共享這個活動的實例,應該如何實現呢?使用前面三種啓動模式肯定是做不到的,因爲每個應用程序都會有自己的返回棧,同一個活動在不同的返回棧中入棧時必然是創建了新的實例。而使用singleInstance模式就可以解決這個問題,在這種模式下會有一個單獨的返回棧來管理這個活動,不管是哪個應用程序來訪問這個活動,都共用的同一個返回棧,也就解決了共享活動實例的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章