重溫Android四大元件—Activity的生命週期

Codeing_ls發表於2019-04-20

前言

四大元件對於Android開發者是老生常談的知識了,相信每個Android開發者對四大元件都已經很熟悉了。但是四大元件作為Android應用的基礎,作為開發者不僅要熟悉而且要爛熟於心。

這裡以《重溫Android四大元件》為題目是為了鞏固自己的Android基礎,加深對Android的認知。

Activity生命週期探索

Activity生命週期是Activity在不同場景下表現的一種狀態,在Android開發中的表現就是提供給開發者的生命週期函式。使用Activity生命週期函式的目的就是定義Activity在不同時期的表現。下圖是Android官方文件中提供的Activity生命週期函式回撥。在這張圖中可以看到Activity在各種場景中的狀態變化。

  • onCreate() 表示Activity正在被建立。在系統首次建立時觸發,並且onCreate在整個Activity生命週期中只觸發一次。在onCreate中我們可以做一些初始化工作。

  • onStart() 表示Activity正在啟動。此時Activity對使用者可見,並且正在準備進入前臺並且變得可互動。

  • onReStart() 表示Activity正在重新啟動。一般來說Activity從後臺回到前臺時會呼叫onRestart方法。比如,使用者點選home鍵將Activity放到後臺,然後返回應用。

  • onResume() 表示Activity已經進入到前臺,使用者可以與Activity進行互動了。Activity將會停留在resume狀態直到有其它事件發生時Activity失去焦點,比如說使用者切換到其它Activity。

  • onPause() 表示Activity正在停止。也就是說某些事件發生導致使用者正在離開當前Activity。在onPause方法中可以釋放一些系統資源,比如感測器或者可能影響電池續航的一些行為。但是需要注意的時不能再onPause中作耗時操作,因為在啟動其他Activity時,執行過當前Activity的onPause方法後才會執行新的Activity的onResume方法。

  • onStop() 表示Activity即將停止。此時Activity對使用者已經是不可見的了,但是此時Activity物件依然在記憶體中。在onStop中可以做一些稍微重量級的操作,比如資料庫操作、暫停動畫或者處理一些對使用者不可見的資源。

  • onDestroy() 表示Activity將要銷燬。這是Activity生命週期中的最後一個回撥函式。在onDestroy方法中需要釋放所有資源。

Activity生命週期

Activity在不同場景中的生命週期狀態

(1)Activity被啟動並結束

觸發條件:使用者按下back鍵或者呼叫了Activity的finish方法。

這個簡單的場景是最常出現的。這個場景可以歸納為:onCreate()->onStart()-onResume()->點選返回鍵->onPause()->onStop()->onDestroy()

(2)使用者切換出當前應用

觸發條件:使用者按下HOME鍵或者在工作列中切換到其它應用。

在這個場景中Activity被放到後臺,但是並沒有被銷燬,Activity例項依然在記憶體中,如果系統沒有回收程式,Activity例項會保有之前的狀態。這個場景可以歸納為:onCreate()->onStart()-onResume()->點選HOME鍵->onPause()->onStop()->onSaveInstanceState()->返回應用->onRestart()->onStart()->onResume()

(3)系統配置變化

觸發條件:比如:螢幕方向改變、鍵盤語言變化等。

在上述條件中,螢幕方向改變應該是最常見的現象。系統配置的改變會導致Activity的銷燬以及重建。生命週期變化是:onCreate()->onStart()->onResume()->螢幕方向變化->onPause()->onStop()->onSaveInstanceState()->onDestory()->onCreate()->onStart()->onRestoreInstanceState()->onResume()。

可以看到在螢幕方向變化期間,Activity經歷了銷燬和重建兩個過程。可以注意到在這期間有兩個方法被呼叫到,它們分別是onSaveInstanceState和onRestoreInstanceState,這兩個方法時用來恢復Activity狀態使用的,通過Bundle傳遞引數。

在上面的情況中,由於Bundle無法傳遞大量的資料,開發者可以選擇自己處理系統配置變化。在AndroidManifest.xml檔案中改變Activity的配置。比如,處理螢幕方向改變可以加入配置:android:configChanges="orientation"。這個時候螢幕方向改變是就會呼叫onConfigurationChanged方法。此時的生命週期變化是:onCreate()->onStart()->onResume()->螢幕方向變化->onConfigurationChanged()。

可以看到,如果開發者自己處理系統配置改變,那麼Activity就不會銷燬重建了,而是直接呼叫onConfigurationChanged方法。

(4)啟動模式對生命週期的影響

我們知道Activity有4中啟動模式,分別是standard(標準模式)、singleTop(棧頂複用模式)、singleTask(棧內複用模式)、singleInstance(單例項模式)。啟動模式不同也會導致Activity生命週期不同的變化。

  • standard(標準模式):標準模式下的Activity在每次啟動時都會建立新的Activity例項,它的生命週期跟上面圖中所示相差無幾。

  • singleTop(棧頂複用模式):在這種模式下的Activity如果處於Activity棧棧頂,那麼會複用Activity例項,啟動的時候就會呼叫onNewIntent()->onRestart()->onStart()->onResume()。如果不是處於棧頂就會呼叫onCreate()->onRestart()->onStart()->onResume()。

  • singleTask(棧內複用模式):在這個模式下的Activity只要在Activity棧記憶體在例項就會複用這個例項,那個生命週期變化是:onNewIntent()->onRestart()->onStart()->onResume()。

  • singleInstance(單例項模式):在這種模式下Activity單獨存在一個Activity棧中,啟動呼叫onCreate()->onRestart()->onStart()->onResume()

通過Activity生命週期函式記錄Activity狀態

在上面的系統配置變化的例子中可以看到Activity中提供了記錄狀態的方法。onSaveInstanceState以及onRestoreInstanceState,這兩個方法都是用Bundle。除此之外我們還能看到在onCreate方法中也有一個Bundle型別的引數,這個Bundle就是儲存的狀態的載體。

我們知道Activity會由於一些行為被銷燬,比如,退出Activity。這些正常的操作會銷燬Activity例項,並且系統不會保有Activity的狀態。還有一種情況是當Activity處於後臺時,由於記憶體問題會被系統回收或者系統配置改變導致的銷燬重建,這個時候系統會保有Activity的狀態,就是Bundle儲存的資料,在Activity重建是會獲取到Bundle中的資料。

總結

在上面介紹了Activity在各種場景下的生命週期表現。理解這些生命週期的呼叫有利於在開發時更好的處理Activity與使用者的互動,同時也能避開一些常見的問題。

相關文章