Android Kotlin 基本概念 04.1:生命週期和記錄

本程式碼研究室是 Android Kotlin 基礎課程的一部分。使用程式碼研究室逐步完成程式碼課程後,您將能充分發揮本課程的潛能。所有課程程式碼研究室清單均列於 Android Kotlin 基礎程式碼研究室到達網頁

簡介

在這個程式碼研究室中,您將瞭解 Android 的基本部分:活動和片段生命週期。活動生命週期是指一組活動在其生命週期中的可能狀態。生命週期是指活動從最初建立到刪除的這段期間,且系統會回收該活動的資源。當使用者在應用程式中瀏覽活動 (以及進入及離開應用程式) 時,這些活動會在活動生命週期中的不同狀態之間進行轉換。

片段生命週期與活動非常相似,本程式碼研究室主要是進行活動,一目了然地將重點放在結尾。

身為 Android 開發人員,您必須瞭解活動生命週期。如果您的活動未正確回應生命週期狀態變更,應用程式可能會產生異常錯誤、造成使用者混淆行為,或耗用過多 Android 系統資源。瞭解 Android 生命週期,並正確回應生命週期狀態變更,是成為 Android 優良使用者的重要條件。

須知事項

  • 何謂活動,以及如何在應用程式中建立活動。
  • 活動 (onCreate()) 方法的用途,以及該方法執行的操作類型。
  • 如何為活動建立 XML 版面配置,以及如何在執行階段更新版面配置。

您將會瞭解的內容

  • 如何將紀錄資訊列印至 Logcat (有時稱為 Android 控制台或 Android 螢幕)。
  • ActivityFragment 生命週期的基本資訊,以及活動在狀態之間移動時叫用的回呼。
  • 如何覆寫生命週期回呼方法,以在活動生命週期的不同時間點執行運算。
  • 如何使用 Timber 程式庫在應用程式中記錄資料。

實際做法

  • 修改名為 DessertClicker 的範例應用程式,以新增 Logcat 中顯示的記錄資訊。
  • 覆寫生命週期回呼方法,並記錄活動狀態的變更。
  • 執行應用程式,並記下活動開始、停止和繼續時的記錄資訊。
  • 修改應用程式以使用 Timber 程式庫。
  • 新增紀錄至 AndroidTrivia 應用程式,並監控片段狀態的變更。

在本程式碼研究室中,您將使用名為 DessertClicker 的範例應用程式。在此應用程式中,每當使用者輕觸畫面上的甜點,應用程式就會為使用者「購買」甜點。應用程式會更新版面配置中的值數量,以購買購買的甜點數量以及使用者的消費總金額。

這個應用程式包含數個與 Android 生命週期相關的錯誤:例如,在某些情況下,應用程式會將甜點的值重設為 0,即使應用程式會在背景執行,應用程式仍會繼續使用系統資源。瞭解 Android 生命週期有助於瞭解發生這些問題的原因和修正方法。

每個活動與每個片段都有所謂的生命週期。這是動物的生命週期,如這個蝴蝶的生命週期;不同蝴蝶的存在狀態顯示了生育從成年到成熟的成年人,從成年到成熟的成熟度。

同樣地,活動生命週期由活動可能經歷的不同狀態組成,從活動首次初始化到最終刪除,且系統回收其記憶體的這段時間。當使用者啟動您的應用程式、瀏覽活動、瀏覽應用程式內部或外部,而離開應用程式時,活動狀態也會隨之改變。下圖顯示所有活動生命週期狀態。顧名思義,這些狀態代表活動的狀態。

通常,當活動生命週期狀態變更時,您會想變更部分行為或執行某些程式碼。因此,Activity 類別本身和 Activity 的任何子類別 (例如 AppCompatActivity) 會實作一系列生命週期回呼方法。當活動狀態改變時,Android 將會叫用這些回呼,而您可以在自身活動中覆寫此類方法,以執行回應生命週期狀態變更的工作。下圖顯示生命週期狀態,以及可用的可覆寫回呼。

片段也有生命週期。片段的生命週期與活動的生命週期類似,因此您可以學到許多知識。在這個程式碼研究室中,您將重點放在活動生命週期,因為它是 Android 的基本部分,也是簡易應用程式最容易觀察到的部分。以下是片段生命週期的對應圖表:

請務必瞭解這些回呼的叫用時機,以及每個回呼方法的處理方式。但兩個圖表都很複雜,可能會令人感到困惑。在這個程式碼研究室中,您不必閱讀每個狀態和回呼所代表的意義,而是進行一些偵探工作,並且瞭解您的瞭解。

步驟 1:檢查 onCreate() 方法並新增記錄

如要瞭解 Android 生命週期發生的情況,瞭解呼叫各種生命週期方法的時機相當實用。這有助於您找出 DessertClicker 中的問題。

只要使用 Android Logging API 即可輕鬆達成這個目的。記錄功能可讓您在應用程式執行期間,將簡短訊息寫入主控台,以便顯示不同回呼觸發的時間。

  1. 下載 DessertClicker 入門應用程式,並在 Android Studio 中開啟該應用程式。
  2. 編譯並執行應用程式,接著輕觸甜點圖片上的數次。請注意「Desserts Sold」(售出甜點) 值和總金額的變化情況。
  3. 開啟 MainActivity.kt 並檢查這項活動的 onCreate() 方法
override fun onCreate(savedInstanceState: Bundle?) {
...
}

在活動生命週期圖表中,您可能已認出 onCreate() 方法,因為您先前使用過此回呼。這是每項活動都必須實作的方法。onCreate() 是您為活動執行任何一次性初始化作業的方法。舉例來說,在 onCreate() 中,您可以展開版面配置、定義點擊接聽器或設定資料繫結。

當活動初始化後 (在記憶體中建立新的 Activity 物件時),系統會呼叫 onCreate() 生命週期方法一次。onCreate() 執行後,系統會將該活動視為已建立的活動。

  1. onCreate() 方法中,剛剛呼叫 super.onCreate() 之後,加入以下這一行。視需要匯入 Log 類別。(在 Mac 上請按 Alt+Enter,或是選取 Option+Enter,然後選取 [匯入])。
Log.i("MainActivity", "onCreate Called")

Log 類別會將訊息寫入 Logcat。這個指令有三個部分:

  • 記錄訊息的「嚴重程度」,也就是郵件的重要性。在這種情況下,Log.i() 方法會寫入資訊訊息。Log 類別的其他方法包括 Log.e() 發生錯誤,或 Log.w() 顯示警告。
  • 記錄 tag,在本例中為 "MainActivity"。這個標記是字串,可讓您在 Logcat 中輕鬆找到您的記錄訊息。標記通常為類別的名稱。
  • 實際的記錄 message 是短字串,在本例中為 "onCreate called"
  1. 編譯並執行 DessertClicker 應用程式。輕觸甜點時,就不會在應用程式中看到任何行為差異。在 Android Studio 中,按一下畫面底部的 [Logcat] 分頁標籤。



    Logcat 是記錄訊息的主控台。這裡會顯示與您應用程式相關的 Android 相關訊息,包括您明確透過 Log.i() 方法或其他 Log 類別方法傳送到記錄的訊息。
  2. 在「Logcat」窗格中,在搜尋欄位中輸入「I/MainActivity」。


    Logcat 可包含許多訊息,其中多數訊息對您來說不實用。您可以透過多種方式篩選 Logcat 項目,但搜尋是最簡單的方法。由於您在程式碼中使用了 MainActivity 做為記錄標記,因此您可以使用該標記篩選記錄。加入 I/ 表示這是由 Log.i() 所建立的資訊訊息。

    您的記錄訊息包含日期和時間、包裹名稱 (com.example.android.dessertclicker)、記錄標記 (開頭是 I/) 以及實際訊息。由於這則訊息出現在記錄中,因此您知道「onCreate()」已執行完畢。

步驟 2:實作 onStart() 方法

系統將在 onCreate() 之後呼叫 onStart() 生命週期方法。onStart() 開始執行後,螢幕上會顯示您的活動。有別於 onCreate() 只會初始化您的活動,因此系統可以在活動的生命週期中多次呼叫 onStart()

請注意,onStart() 已和對應的 onStop() 生命週期方法配對。如果使用者啟動您的應用程式,然後返回裝置的主畫面,活動就會停止,不再顯示在畫面上。

  1. 在 Android Studio 中開啟「MainActivity.kt」後,選取 [程式碼 &覆寫方法] 或按下 Control+o 鍵。畫面上會出現一個對話方塊,內含可在此類別中覆寫的所有方法。
  2. 輸入 onStart 以搜尋正確方法。如要捲動至下一個相符的項目,請使用向下鍵。從清單中選擇 onStart(),然後按一下「確定」,以插入樣板覆寫程式碼。程式碼如下所示:
override fun onStart() {
   super.onStart()
}
  1. onStart() 方法中加入記錄訊息:
override fun onStart() {
   super.onStart()

   Log.i("MainActivity", "onStart Called")
}
  1. 編譯並執行 DessertClicker 應用程式,然後開啟「Logcat」窗格。在搜尋欄位中輸入 I/MainActivity,以篩選記錄。請注意,onCreate()onStart() 這兩種方法都會以另一種方式呼叫,且您的活動會在螢幕上顯示。
  2. 按下裝置的主畫面按鈕,然後使用最近使用畫面返回活動。請注意,活動會從上次中斷的地方接續進行,所有值皆相同,且系統會將 onStart() 再次記錄到 Logcat。另請注意,系統通常不會再次呼叫 onCreate() 方法。

在這項工作中,您將修改應用程式,以使用名為 Timber 的熱門紀錄程式庫。相較於內建 Android LogTimber 具備幾項優點。特別是 Timber 程式庫:

  • 根據類別名稱產生記錄標記。
  • 協助您避免在 Android 應用程式版本中顯示記錄。
  • 允許與當機報告程式庫整合。

您會立即看到第一項福利,其他創作者也會因為開發及發布大型應用程式而受益。

步驟 1:在 TiGradle 中新增 Timber

  1. 前往 GitHub 的「Timber 專案」連結,然後將「下載」標題下方的程式碼行複製,開頭為 implementation 字樣。程式碼行看起來會像這樣,不過版本號碼可能會不同。
implementation 'com.jakewharton.timber:timber:4.7.1'
  1. 在 Android Studio 的「Project: Android」檢視畫面中,展開 Gradle 指令碼並開啟 build.gradle (模組:應用程式) 檔案。
  2. 在「依附元件」部分中,貼上您複製的程式碼行。
dependencies {
   ...
   implementation 'com.jakewharton.timber:timber:4.7.1'
}
  1. 按一下 Android Studio 右上角的 [立即同步處理] 連結,即可重新建構 Gradle。執行時不應出現錯誤。

步驟 2:建立應用程式類別並初始化 Timber

在這個步驟中,您會建立 Application 類別。Application 是基礎類別,包含您整個應用程式的全域應用程式狀態。系統也是作業系統用來與應用程式互動的主要物件。如果您沒有指定其中一個類別,Android 會使用預設的 Application 類別,因此您不必另外為應用程式建立 Application 物件,完全不需要建立特別的物件。

Timber」會使用 Application 類別,因為整個應用程式都會使用這個記錄資料庫,且必須在設定其他資料庫前初始化一次程式庫。在這種情況下,您可以將 Application 類別設為子類別,並使用自己的自訂導入方式覆寫預設值。

建立 Application 類別後,您必須在 Android 資訊清單中指定類別。

  1. dessertclicker 套件中,新建名為 ClickerApplication 的 Kotlin 類別。方法是展開 app > java,然後在 com.example.android.dessertclicker 上按一下滑鼠右鍵。選取 [New > Kotlin File/Class]
  2. 將類別命名為 ClickerApplication,並將 Kind 設為 Class按一下 [確定]。

Android Studio 會建立新的 ClickerApplication 類別,並在程式碼編輯器中開啟該類別。程式碼的格式如下:

package com.example.android.dessertclicker

class ClickerApplication {
}
  1. 將類別定義變更為 Application 的子類別,並視需要匯入 Application 類別。
class ClickerApplication : Application() {
  1. 如要覆寫 onCreate() 方法,請選取 [Code > Override Methods] (程式碼程式碼的覆寫值),或按下 Control+o 鍵。
class ClickerApplication : Application() {
   override fun onCreate() {
       super.onCreate()
   }
}
  1. 在這個 onCreate() 方法中,初始化 Timber 程式庫:
override fun onCreate() {
    super.onCreate()

    Timber.plant(Timber.DebugTree())
}

這行程式碼會將應用程式的 Timber 程式庫初始化,方便您在活動中使用該程式庫。

  1. 開啟 AndroidManifest.xml
  2. <application> 元素頂端新增 ClickerApplication 類別的新屬性,讓 Android 知道使用您的 Application 類別 (而不是預設類別)。
<application
   android:name=".ClickerApplication"
...

步驟 3:新增 Tim 記錄陳述式

在這個步驟中,您會變更 Log.i() 呼叫以使用 Timber,然後針對所有其他生命週期方法導入記錄。

  1. 開啟「MainActivity」並捲動至「onCreate()」。將 Log.i() 替換為 Timber.i() 並移除記錄標記。
Timber.i("onCreate called")

如同 Log 類別,Timber 也會使用 i() 方法來提供資訊訊息。請注意,使用 Timber 時,您不需要新增紀錄標記;Timber 會自動使用類別的名稱做為記錄標記。

  1. 同樣地,變更 onStart() 中的 Log 呼叫:
override fun onStart() {
   super.onStart()

   Timber.i("onStart Called")
}
  1. 編譯並執行 DessertClicker 應用程式,然後開啟 Logcat。您仍然會看到與 onCreate()onStart() 相同的記錄訊息,這只是Timber的產生訊息,而不是 Log 類別。
  2. 覆寫 MainActivity 中的生命週期方法的其餘部分,並為每個方法新增 Timber 記錄陳述式。程式碼如下:
override fun onResume() {
   super.onResume()
   Timber.i("onResume Called")
}

override fun onPause() {
   super.onPause()
   Timber.i("onPause Called")
}

override fun onStop() {
   super.onStop()
   Timber.i("onStop Called")
}

override fun onDestroy() {
   super.onDestroy()
   Timber.i("onDestroy Called")
}

override fun onRestart() {
   super.onRestart()
   Timber.i("onRestart Called")
}
  1. 再次編譯並執行 DessertClicker,並檢查 Logcat。這次請注意,除了 onCreate()onStart() 以外,系統也會提供 onResume() 生命週期回呼的記錄訊息。

活動從頭開始時,系統會依序呼叫下列三個生命週期回呼:

  • onCreate() 以建立應用程式。
  • onStart() 可啟動活動並在螢幕上顯示。
  • onResume()可讓活動成為焦點,讓使用者可以與應用程式互動。

儘管如此,即使沒有可恢復的項目,啟動時仍會呼叫 onResume() 方法。

現在,DessertClicker 應用程式已進行記錄設定,您可以透過各種方式開始使用該應用程式,並探索如何觸發生命週期回呼,以回應用途。

用途 1:開啟及關閉活動

您將從最基本的用途開始,也就是初次啟動應用程式,然後完全關閉應用程式。

  1. 編譯並執行 DessertClicker 應用程式 (如果尚未執行)。如您所見,在活動第一次開始時,系統會呼叫 onCreate()onStart()onResume() 回呼。
  2. 輕觸杯子蛋糕數次。
  3. 輕觸裝置上的 [返回] 按鈕。請注意,Logcat 會依序呼叫 onPause()onStop()onDestroy()

    在這個案例中,使用 [返回] 按鈕會導致活動 (以及應用程式) 完全關閉。如果執行 onDestroy() 方法,表示活動已完全關閉,可以進行垃圾收集。垃圾收集是指自動清除您不再使用的物件。呼叫 onDestroy() 後,作業系統就知道可以捨棄這些資源,並且開始清理記憶體。

    如果您的程式碼手動呼叫該活動的 finish() 方法,或者使用者強制退出應用程式,也可以完全關閉您的活動 (例如,使用者可以按一下視窗角落的 [X] 強制退出應用程式)。若應用程式長時間未處於畫面上,Android 系統也可能會自行關閉您的活動。Android 這麼做是為了延長電池用量,並讓其他應用程式使用您的應用程式資源。
  4. 使用「最近」畫面返回應用程式。這裡是 Logcat:


    您在前一個步驟中已經刪除該活動,因此當您返回應用程式時,Android 會啟動新的活動,並呼叫 onCreate()onStart()onResume() 方法。請注意,先前活動的 DessertClicker 統計資料並未保留。

    這裡的重點在於,在單一活動實例的生命週期內,系統只會呼叫 onCreate()onDestroy():這是第一次為應用程式初始化的時間,而 onDestroy() 則是用於清除應用程式使用的資源。

    onCreate()

用途 2:離開後再返回活動

現在,您已啟動並完全關閉應用程式,您可看到活動首次建立時的大部分生命週期狀態。此外,您也會看到活動完全關閉且刪除後經歷的所有生命週期狀態。不過,使用者與 Android 裝置互動時,他們會切換使用不同應用程式,例如返回住家、啟動新應用程式及處理其他活動 (例如來電)。

使用者每次離開該活動時,您的活動並不會完全關閉:

  • 當系統不再於畫面中顯示活動時,即稱為使活動進入背景。(反之,則活動位於前景或螢幕上。)
  • 使用者返回您的應用程式時,系統會重新啟動相同的活動,並再次顯示該活動。生命週期中的此部分稱為應用程式的可見生命週期。

應用程式於背景執行時,不應主動執行,以節省系統資源及延長電池續航力。您會使用 Activity 生命週期及其回呼來瞭解應用程式移至背景的時間,以便暫停任何進行中的作業。接著您會在應用程式進入前景時重新開始作業。

舉例來說,假設某個應用程式執行物理模擬,需要經過多次計算,這項技術會根據裝置的 CPU如果通話中斷會造成模擬作業,使用者可能會感到困惑,甚至感到不滿,甚至返回應用程式查看模擬結果。

另外,這項技術也能帶來成效假設使用者開啟了 20 款使用 CPU 密集型物理模擬的應用程式。如果這些應用程式:螢幕上的活動並不在螢幕,但背景仍進行大量轉譯,這會使整個手機的效能變慢。

在這個步驟中,您將檢視應用程式在背景執行並再次回到前景時的活動生命週期。

  1. 執行 DessertClicker 應用程式時,點選杯子蛋糕數次。
  2. 按下裝置的主螢幕按鈕,在 Android Studio 中觀察 Logcat。返回主畫面會讓應用程式進入背景,而非完全關閉應用程式。請注意,系統會呼叫 onPause() 方法和 onStop() 方法,但不會呼叫 onDestroy()


    呼叫 onPause() 時,應用程式不再聚焦。onStop()後,該應用程式就不會再顯示於畫面上。雖然活動已停止,但 Activity 物件仍在背景中,系統並未刪除該活動。使用者可能會回到應用程式,因此 Android 可以保留你的活動資源。
  3. 使用「最近」畫面返回應用程式。請注意,Logcat 會以 onRestart()onStart() 重新開始活動,然後透過 onResume() 恢復活動。


    當活動返回前景時,不會再次呼叫 onCreate() 方法。活動物件並未刪除,因此不需要重新建立。系統會呼叫 onRestart() 方法,而不是 onCreate()。請注意,當活動回到前景時,系統會保留 Desserts Sold 這個數字。
  4. 請至少啟動 DessertClicker 以外的一個應用程式,這樣一來,裝置在最近的「最近」畫面中就會列出數個應用程式。
  5. 開啟最近使用畫面,並開啟其他最近活動。接著,返回最近使用的應用程式,並將 DessertClicker 帶回前景。

    請注意,登入 Logcat 後,你按下的按鍵動作會與按下主螢幕按鈕時相同。當應用程式進入背景時,系統會呼叫 onPause()onStop(),然後再傳回 onRestart()onStart()onResume()

    這裡的重點在於,當使用者進入活動及離開活動時,系統會多次呼叫 onStart()onStop()。你應該覆寫這些方法,以便在應用程式進入背景時停止應用程式,或在應用程式返回前景時重新開始。

    那該怎麼因應?onRestart()onRestart() 方法與 onCreate() 類似。onCreate()onRestart() 會在活動出現前呼叫。第一次只會呼叫 onCreate() 方法,之後會呼叫 onRestart()onRestart() 方法是您只有在能夠「初次」開始活動時才要呼叫的程式碼。

用途 3:部分隱藏活動

您已經瞭解應用程式啟動且呼叫 onStart() 時,螢幕上會顯示該應用程式。應用程式恢復運作並呼叫 onResume() 後,應用程式就會取得使用者焦點。在生命週期中,應用程式全螢幕顯示並聚焦於使用者生命週期的部分稱為「互動式」生命週期。

應用程式進入背景後,焦點會在 onPause()後消失,且應用程式在 onStop()之後就不會再顯示。

焦點和可見度之間的差異非常重要,因為活動在畫面上可以部分顯示,但沒有使用者焦點。在此步驟中,可查看部分顯示,但沒有使用者焦點的活動。

  1. 在執行 DessertClicker 應用程式時,按一下畫面右上方的 [分享] 按鈕。




    分享活動會顯示在畫面下半部,但前半部仍會顯示該活動。
  2. 檢查 Logcat,並只呼叫 onPause()


    在這個案例中,由於活動的部分處於可見狀態,因此不會呼叫 onStop()。但是,活動並非以使用者為中心,所以使用者無法與其互動。「前景」的活動在前景執行時,會把焦點放在使用者身上。

    為什麼這項差異很重要?您可以考慮使用物理應用程式。當應用程式在背景中執行時,您可能會希望模擬作業停止執行,並在應用程式的部分內容變得模糊時繼續執行。在這種情況下,您將停止 onStop() 中的模擬作業。如果希望模擬活動在部分活動完成時停止模擬,請將程式碼設為在 onPause() 後停止模擬。

    無論在 onPause() 中執行哪些程式碼,都會禁止顯示其他內容,因此請將程式碼維持 onPause() 輕量。舉例來說,如果有來電,「onPause()」中的驗證碼可能會延遲來電通知。
  3. 按一下分享對話方塊外的方塊即可返回應用程式,並注意到 onResume() 已呼叫。

    onResume()onPause() 都必須對焦。當活動成為焦點時,系統會呼叫 onResume() 方法;而活動遺失時則呼叫 onPause()

Android 片段生命週期與活動生命週期類似,還有一些片段專屬方法。

在這項工作中,您會檢視先前在程式碼研究室中建立的 AndroidTrivia 應用程式,並新增一些紀錄來探索片段生命週期。您可以透過 AndroidTrivia 應用程式回答 Android 開發作業相關問題,只要連續回答三個問題,就能贏得比賽。

AndroidTrivia 應用程式中的每個畫面都是 Fragment

為了簡化作業,您必須在這項工作中使用 Android Logging API,而不是 Timber Library。

  1. 從最後一個程式碼研究室開啟 AndroidTrivia 應用程式,或從 GitHub 下載 AndroidTrivia 解決方案程式碼。
  2. 開啟 TitleFragment.kt 檔案。請注意,在您重新建立應用程式前,Android Studio 可能會顯示繫結錯誤和未解決的參照錯誤。
  3. 向下捲動至「onCreateView()」方法。請注意,這是將版面配置的版面配置展開,並產生資料繫結的情況。
  4. onCreateView() 方法中新增記錄陳述式,在 setHasOptionsMenu() 行與最後傳回呼叫之間的呼叫之間:
setHasOptionsMenu(true)

Log.i("TitleFragment", "onCreateView called")

return binding.root
  1. onCreateView() 方法的下方,為每個其他的片段生命週期方法新增記錄陳述式。程式碼如下:
override fun onAttach(context: Context?) {
   super.onAttach(context)
   Log.i("TitleFragment", "onAttach called")
}
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   Log.i("TitleFragment", "onCreate called")
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
   super.onActivityCreated(savedInstanceState)
   Log.i("TitleFragment", "onActivityCreated called")
}
override fun onStart() {
   super.onStart()
   Log.i("TitleFragment", "onStart called")
}
override fun onResume() {
   super.onResume()
   Log.i("TitleFragment", "onResume called")
}
override fun onPause() {
   super.onPause()
   Log.i("TitleFragment", "onPause called")
}
override fun onStop() {
   super.onStop()
   Log.i("TitleFragment", "onStop called")
}
override fun onDestroyView() {
   super.onDestroyView()
   Log.i("TitleFragment", "onDestroyView called")
}
override fun onDetach() {
   super.onDetach()
   Log.i("TitleFragment", "onDetach called")
}
  1. 編譯並執行應用程式,然後開啟 Logcat。
  2. 在搜尋欄位中輸入「I/TitleFragment」,即可篩選記錄。應用程式啟動後,Logcat 會顯示類似以下的螢幕截圖:

您可以在此查看片段的完整啟動生命週期,包括這些回呼:

  • onAttach():在片段與其擁有者活動建立關聯時呼叫。
  • onCreate():與活動的 onCreate() 類似,呼叫片段的 onCreate() 會進行初始片段建立作業 (版面配置除外)。
  • onCreateView():呼叫以呼叫片段的版面配置。
  • onActivityCreated():擁有者活動於 onCreate()完成時呼叫。您必須呼叫這個方法,您的片段才能存取活動。
  • onStart():當片段變為可見時呼叫;與活動 onStart() 平行時呼叫。
  • onResume():當片段獲得使用者焦點時呼叫;與活動 onResume() 平行時呼叫。
  1. 輕觸 [開始玩] 按鈕可前往益智問答遊戲,馬上查看 Logcat。

開啟下一個片段會導致標題片段關閉,並呼叫下列生命週期方法:

  • onPause():當片段失去使用者焦點時呼叫,與活動 onPause() 平行。
  • onStop():當片段不再顯示在螢幕上時呼叫;與活動 onStop() 平行時呼叫。
  • onDestroyView():不再需要片段檢視時呼叫,以清理與該檢視相關的資源。
  1. 在應用程式中輕觸「向上」按鈕 (畫面左上角中的箭頭) 即可返回標題片段。


    這次,onAttach()onCreate() 可能不會呼叫以啟動片段。片段物件仍然存在,且仍會附加至擁有者的活動,因此生命週期會從 onCreateView() 重新開始。
  2. 按下裝置的主螢幕按鈕。請注意,Logcat 中只會呼叫 onPause()onStop()。這與活動的運作方式相同:返回主螢幕會將活動和片段背景移至背景。
  3. 使用最近的畫面來返回應用程式。如同活動一樣,系統呼叫 onStart()onResume() 方法會將片段傳回至前景。

Android Studio 專案:DessertClickerLogs

活動生命週期

  • 活動生命週期是一組活動轉移的狀態。活動生命週期是從首次建立時開始,並在活動刪除時結束。
  • 使用者在活動間及應用程式內外瀏覽時,每個活動會在活動生命週期中的狀態間移動。
  • 活動生命週期中的每個狀態都有相應的回呼方法,可在 Activity 類別中覆寫。生命週期方法有七種:
    onCreate()
    onStart()
    onPause()
    onRestart()
    onResume()
    onStop()
    onDestroy()
  • 如要新增在活動轉換為生命週期狀態時發生的行為,請覆寫狀態的回呼方法。
  • 如要在 Android Studio 中新增架構覆寫方法,請選取「程式碼」>「覆寫方法」,或按下 Control+o

使用記錄檔進行記錄

  • Android 記錄 API (尤其是 Log 類別) 可讓您撰寫顯示在 Android Studio 中 Logcat 的簡短訊息。
  • 使用Log.i()撰寫資訊訊息。此方法使用兩個引數:記錄 tag (通常是類別名稱) 以及紀錄 message (短字串)。
  • 使用 Android Studio 中的 Logcat 窗格查看系統紀錄,包括您撰寫的訊息。

使用 Timber 進行記錄

Timber 是一個記錄庫,與 Android Logging API 相比有許多好處。特別是 Timber 程式庫:

  • 根據類別名稱產生記錄標記。
  • 有助於避免在 Android 應用程式版本中顯示記錄。
  • 允許整合當機回報程式庫。

如要使用 Timber,請將依附元件加入 Gradle 檔案,並擴充 Application 類別來初始化該檔案:

  • Application 是基礎應用程式類別,包含整個應用程式的全域應用程式狀態。如果您沒有指定類別,Android 會使用預設的 Application 類別。您可以建立自己的 Application 子類別來初始化整個應用程式的程式庫,例如 Timber
  • android:name 屬性新增至 Android 資訊清單中的 <application> 元素,即可將自訂 Application 類別新增至應用程式。別忘了執行這個動作!
  • 使用 Timber.i()Timber 寫入記錄訊息。此方法只會使用一個引數:要寫入的訊息。系統會自動為您新增記錄標記 (類別名稱)。

Udacity 課程:

Android 開發人員說明文件:

其他:

這個部分會列出在代碼研究室中,受老師主導的課程作業的可能學生作業。由老師自行決定要執行下列動作:

  • 視需要指派家庭作業。
  • 告知學生如何提交家庭作業。
  • 批改家庭作業。

老師可視需要使用這些建議,並視情況指派其他合適的家庭作業。

如果您是自行操作本程式碼研究室,歡迎透過這些家庭作業來測試自己的知識。

變更應用程式

開啟第 1 課的 DiceRoller 應用程式。(如果您沒有這個應用程式,可以在這裡下載 DiceRoller 應用程式)。使用與 DessertClicker 應用程式相同的程序,為該應用程式新增 Timber 支援。覆寫所有生命週期回呼,並為每個回呼新增記錄訊息。

回答這些問題

第 1 題

下列何者「不是」活動生命週期狀態?

  • 已啟動
  • 等待中
  • 建立時間
  • 已刪除

第 2 題

若要讓活動顯示,應該要呼叫哪一個生命週期方法?

  • onPause()
  • onVisible()
  • onStart()
  • onDestroy()

第 3 題

若要提供活動聚焦,應該要呼叫哪一個生命週期方法?

  • onResume()
  • onVisible()
  • onStart()
  • onFocus()

第 4 題

活動何時會呼叫 onCreate()

  • 每當使用者看到活動時,都會產生一筆記錄。
  • 每次活動從背景傳回時。
  • 建立活動時只會執行一次。
  • 僅恢復活動一次。

提交應用程式進行評分

確認該應用程式是否符合下列條件:

  • 應用程式 build.gradle 檔案的 Timber 依附元件。
  • Application 的自訂子類別,可在 onCreate() 中初始化 Timber
  • Android 資訊清單中自訂自訂子類別的屬性。
  • 所有生命週期回呼方法的 MainActivity 方法都會遭到覆寫,並會呼叫 Timber.i() 進行記錄。

開始下一門課程:4.2:複雜的生命週期情境

如要瞭解本課程中其他程式碼研究室的連結,請參閱 Android Kotlin 基礎程式碼程式碼到達網頁