Activity生命週期

lcc發表於2021-09-09

目錄

1. Activity的各種生命週期

2. onSaveInstanceState() 與 onRestoreInstanceState()

3. Activity生命週期的變化

4. 總結


1. Activity的各種生命週期

系統中的Activity由Activity堆疊管理,當啟動一個新的Activity的時候,這個Activity被放置在棧頂,並處於正在執行狀態。前一個Activity在堆疊中位於新的Activity下面,並且在新的Activity退出前不會出現在前臺。

下面用一張圖展示Activity完整生命週期:

圖片描述

  • onCreate
    在Activity第一次被建立時呼叫onCreate方法。我們通常在onCreate方法中載入佈局,初始化控制元件。
  • onStart
    在Activity變為可視的時候,呼叫onStart方法。
  • onResume
    當Activity處於棧頂,並處於正在執行狀態,可以與使用者進行互動的時候,呼叫onResume方法。
  • onPause
    當Activity已經失去焦點,且依舊是可視狀態時呼叫onPause方法,此時Activity無法與使用者進行互動。
  • onStop
    當Activity從可視變為不可視的時候,呼叫onStop方法。
  • onDestory
    onDestory方法在Activity被銷燬前呼叫。
  • onRestart
    onRestart方法在Activity被重新啟動時呼叫,在Activity第一次被建立的時候不會呼叫。

完整生命週期:
完整生命週期在Activity第一次建立呼叫onCreate方法到銷燬前呼叫onDestroy方法之間。
可視生命週期:
可視生命週期在Activity呼叫onStart方法變為可視到呼叫onStop方法變為不可視之間。
前臺生命週期:
前臺生命週期在Activity呼叫onResume方法變得可與使用者互動到呼叫onPause方法變得不可與使用者互動之間。

2. onSaveInstanceState() 與 onRestoreInstanceState()

系統在“未經你許可”銷燬Activity時呼叫onSaveInstanceState方法,用於儲存Activity狀態資訊。onRestoreInstanceState方法在Activity被系統銷燬之後恢復Activity時被呼叫,用於恢復Activity狀態資訊。可重寫這兩個方法在系統“未經你許可”銷燬Activity時儲存和恢復你的資料。
所謂“未經你許可”指的是非人為銷燬Activity,例如按下回退鍵退出頁面屬於人為,系統因記憶體不足回收銷燬Activity屬於非人為。

  • 什麼時候呼叫onSaveInstanceState方法
    (1)、當使用者按下HOME鍵時。
    (2)、切換到其他程式時。
    (3)、鎖屏時。
    (4)、啟動新的Activity時。
    (5)、螢幕方向切換時。

  • 什麼時候呼叫onRestoreInstanceState方法
    在Activity被系統銷燬,又回到該Activity的時候。如使用者按下HOME鍵又馬上返回該Activity,這個時候該Activity一般不會因為記憶體不足而被系統回收,故不呼叫onRestoreInstanceState方法。所以onSaveInstanceState與onRestoreInstanceState不一定會成對被呼叫。

3. Activity生命週期的變化

分別新建3個Activity,MainActivity、TestActivity、TransparentActivity,並在每個Activity中重寫onCreate,onStart,onResume,onPause,onStop,onDestroy,onRestart,onSaveInstanceState,onRestoreInstanceState這9個方法,如下所示:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.act_main)
        Log.e("MainActivity", "onCreate")
    }

    override fun onStart() {
        super.onStart()
        Log.e("MainActivity", "onStart")
    }

    override fun onResume() {
        super.onResume()
        Log.e("MainActivity", "onResume")
    }

    override fun onPause() {
        super.onPause()
        Log.e("MainActivity", "onPause")
    }

    override fun onStop() {
        super.onStop()
        Log.e("MainActivity", "onStop")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.e("MainActivity", "onDestroy")
    }

    override fun onRestart() {
        super.onRestart()
        Log.e("MainActivity", "onRestart")
    }

    override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
        super.onRestoreInstanceState(savedInstanceState)
        Log.e("MainActivity", "onRestoreInstanceState")
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        Log.e("MainActivity", "onSaveInstanceState")
    }
}

程式碼準備好了,來觀察下面各種請看下Activity生命週期的變化:

  • 啟動Activity並點選回退鍵退出Activity

啟動Activity,首先建立Activity,然後頁面變得可見,最後頁面準備好與使用者互動,所以生命週期的呼叫順序應該是 onCreate() -> onStart() -> onResume(),如下圖所示:圖片描述

點選回退鍵退出Activity,首先停止與使用者互動,然後頁面變得不可見,最後銷燬Activity,所以生命週期的呼叫順序應該是 onPause() -> onStop() -> onDestory(),如下圖所示:圖片描述

  • 按下HOME鍵並再次點選應用

按下HOME鍵後,首先頁面停止所有互動,然後頁面變得不可見,最後回到桌面。這時候頁面並沒有被銷燬,只是轉入後臺,但是也存在被系統回收的風險,所以系統會在onPause和onStop之間呼叫onSaveInstanceState方法儲存Activity狀態資訊,所以生命週期的呼叫順序應該是 onPause() -> onSaveInstanceState() -> onStop(),如下圖所示:圖片描述

再次點選應用,如果應用沒有被系統回收,只是從後臺調回前臺,那麼首先是重新開啟頁面,然後頁面變得可見,最後頁面變得可以與使用者互動,所以生命週期的呼叫順序應該是 onRestart() -> onStart() -> onResume(),如下圖所示:圖片描述

  • 切換到其他應用並切回來

當我們切換到其他應用的時候,頁面首先是停止與使用者互動,然後頁面變得不可見,然後進入到別的應用中,由於頁面存在被系統回收的風險,所以系統會在onPause和onStop之間呼叫onSaveInstanceState方法儲存Activity狀態資訊,所以生命週期的呼叫順序應該是 onPause() -> onSaveInstanceState() -> onStop(),如下圖所示:圖片描述

切回來的時候,如果應用沒有被系統回收,首先是重新開啟頁面,然後頁面變得可見,最後頁面變得可以與使用者互動,所以生命週期的呼叫順序應該是 onRestart() -> onStart() -> onResume(),如下圖所示:圖片描述

  • 鎖屏並解鎖

鎖屏的時候,頁面首先是停止與使用者互動,然後頁面變得不可見,然後鎖屏,由於頁面存在被系統回收的風險,所以系統會在onPause和onStop之間呼叫onSaveInstanceState方法儲存Activity狀態資訊,所以生命週期的呼叫順序應該是 onPause() -> onSaveInstanceState() -> onStop(),如下圖所示:圖片描述

解鎖的時候,如果應用沒有被系統回收,首先是重新開啟頁面,然後頁面變得可見,最後頁面變得可以與使用者互動,所以生命週期的呼叫順序應該是 onRestart() -> onStart() -> onResume(),如下圖所示:圖片描述

  • 跳轉到另一個非透明Activity並點選回退鍵返回

從MainActivity跳轉到TestActivity,首先停止MainActivity的互動,然後建立TestActivity,然後TestActivity變得可見,然後TestActivity變得可以與使用者互動,最後MainActivity變得不可見,由於MainActivity存在被系統回收的風險(可能性不大),所以系統會呼叫onSaveInstanceState方法儲存MainActivity狀態資訊。生命週期的呼叫順序如下圖所示:圖片描述

點選回退鍵返回MainActivity,首先停止TestActivity的互動,然後重新開啟MainActivity,然後MainActivity變得可見,然後MainActivity變得可以與使用者互動,然後TestActivity變得不可見,最後TestActivity被銷燬。生命週期的呼叫順序如下圖所示:圖片描述

  • 跳轉到另一個透明Activity並點選回退鍵返回

在styles中建立一個透明的主題:

TransparentActivity在AndroidManifest中宣告透明主題

 

從MainActivity跳轉到透明的Activity,也就是TransparentActivity。由於TransparentActivity是一個透明的Activity,所以他的底層MainActivity還是可視的,所以MainActivity的onStop方法沒有被呼叫,只呼叫了onPause方法。生命週期的呼叫如下圖所示:圖片描述

點選返回鍵,回到MainActivity。因為MainActivity跳轉到TransparentActivity時並沒有變為不可視,所以沒有呼叫onStop,回到MainActivity之後,也不需要重新啟動MainActivity,所以只需要恢復互動就可以了。生命週期的呼叫如下圖所示:圖片描述

  • 由豎屏轉為橫屏

旋轉螢幕後,系統會銷燬然後啟動該Activity,首先停止Activity的互動,然後Activity變得不可見,然後銷燬Activity,銷燬過後啟動Activity,然後Activity變得可見且螢幕旋轉,最後旋轉螢幕過後的Activity變得可以互動。由於旋轉螢幕屬於“未經你許可”銷燬Activity,所以同步執行onSaveInstanceState和onRestoreInstanceState這兩個方法來儲存和恢復Activity的狀態。生命週期的呼叫順序如下圖所示:圖片描述

4. 總結

Activity是Android四大元件之一,也是與使用者互動最頻繁的元件。本篇文章主要總結了Activity的各種生命週期和這些生命週期在不同情況下的變化。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2331/viewspace-2815021/,如需轉載,請註明出處,否則將追究法律責任。

相關文章