Activity 生命周期阶段

1. 开始之前

在本 Codelab 中,您将了解 Android 的一个基本部分:Activity 生命周期

在 Activity 的生命周期中,它会经历各种状态,有时还会返回到之前的状态。这种状态的转换称为 Activity 生命周期。

在 Android 中,Activity 是与用户交互的入口点。

过去,一个 Activity 会在一个应用中显示一个屏幕。根据当前的最佳实践,一个 Activity 可以通过根据需要交换屏幕来显示多个屏幕。

Activity 生命周期从 Activity 的创建到其销毁(系统回收该 Activity 的资源)结束。当用户在 Activity 之间导航时,每个 Activity 都会在 Activity 生命周期中在不同的状态之间转换。

作为 Android 开发人员,您需要了解 Activity 生命周期。如果您的 Activity 没有正确响应生命周期状态更改,您的应用可能会产生奇怪的错误,导致用户感到困惑的行为,或者使用过多的 Android 系统资源。了解 Android 生命周期并正确响应生命周期状态更改是 Android 开发的重要组成部分。

先决条件

  • 了解什么是 Activity 以及如何在应用中创建 Activity
  • 了解 Activity 的 onCreate() 方法的作用以及在该方法中执行的操作类型

您将学到什么

  • 如何将日志信息打印到 Logcat
  • Activity 生命周期基础知识以及 Activity 在状态之间移动时调用的回调
  • 如何覆盖生命周期回调方法以在 Activity 生命周期中的不同时间执行操作

您将构建什么

  • 修改名为 Dessert Clicker 的起始应用,以添加显示在 Logcat 中的日志信息。
  • 覆盖生命周期回调方法并记录 Activity 状态的更改。
  • 运行应用并注意 Activity 启动、停止和恢复时出现的日志信息。
  • 实现 rememberSaveable 以保留可能因设备配置更改而丢失的应用数据。

2. 应用概述

在本 Codelab 中,您将使用名为 Dessert Clicker 的起始应用。在 Dessert Clicker 中,每次用户点击屏幕上的甜点时,应用都会为用户“购买”该甜点。应用会更新布局中的值,用于显示:

  • 已“购买”的甜点数量
  • 已“购买”甜点的总收入

245d0bdfc09f4d54.png

此应用包含几个与 Android 生命周期相关的错误。例如,在某些情况下,应用会将甜点值重置为 0。了解 Android 生命周期将帮助您理解这些问题发生的原因以及如何解决它们。

下载起始代码

在 Android Studio 中,打开 basic-android-kotlin-compose-training-dessert-clicker 文件夹。

3. 探索生命周期方法并添加基本日志记录

每个 Activity 都有一个所谓的生命周期。这个术语暗指植物和动物的生命周期,例如蝴蝶的生命周期——蝴蝶的不同状态显示了它从卵到幼虫到蛹到蝴蝶再到死亡的生长过程。

Butterfly Lifecycle - growth from egg to caterpillar to pupa to butterfly to death.

类似地,Activity 生命周期包括 Activity 可以经历的不同状态,从 Activity 首次初始化到其销毁(此时操作系统 (OS) 会回收其内存)。通常,程序的入口点是 main() 方法。但是,Android Activity 从 onCreate() 方法开始;此方法相当于上面示例中的卵阶段。您已经在本课程中多次使用过 Activity,并且您可能会认出 onCreate() 方法。当用户启动您的应用、在 Activity 之间导航、在应用内外导航时,Activity 都会更改状态。

下图显示了所有 Activity 生命周期状态。顾名思义,这些状态表示 Activity 的状态。请注意,与蝴蝶的生命周期不同,Activity 可以在生命周期中来回切换状态,而不仅仅是单向移动。

ca808edb1c95f07a.png

通常,您希望在 Activity 生命周期状态更改时更改某些行为或运行某些代码。因此,Activity 类本身以及 Activity 的任何子类(例如 ComponentActivity)都实现了一组生命周期回调方法。当 Activity 从一个状态转换到另一个状态时,Android 会调用这些回调,您可以在自己的 Activity 中覆盖这些方法以执行响应这些生命周期状态更改的任务。下图显示了生命周期状态以及可覆盖的回调。

The Activity Lifecycle scheme

了解 Android 何时调用可覆盖的回调以及在每个回调方法中做什么非常重要,但这两张图都比较复杂,可能会让人感到困惑。在本 Codelab 中,您将进行一些侦探工作,构建您对 Android Activity 生命周期的理解,而不是仅仅阅读每个状态和回调的含义。

步骤 1:检查 onCreate() 方法并添加日志记录

要弄清楚 Android 生命周期发生了什么,了解何时调用各种生命周期方法很有帮助。此信息可帮助您识别 Dessert Clicker 应用中出现问题的地方。

确定此信息的一种简单方法是使用 Android 日志记录功能。日志记录使您能够在应用运行时将简短的消息写入控制台,并使用它来查看何时触发不同的回调。

  1. 运行 Dessert Clicker 应用,然后多次点击甜点的图片。请注意 已售甜点 的值和总金额是如何变化的。
  2. 打开 MainActivity.kt 并检查此 Activity 的 onCreate() 方法
override fun onCreate(savedInstanceState: Bundle?) {
    // ...
}

在 Activity 生命周期图中,您可能会认出 onCreate() 方法,因为您之前已经使用过此回调。它是每个 Activity 必须实现的一个方法。在 onCreate() 方法中,您应该执行 Activity 的任何一次性初始化。例如,在 onCreate() 中,您调用 setContent(),它指定 Activity 的 UI 布局。

The onCreate Lifecycle method

在 Activity 初始化 后(即 OS 在内存中创建新的 Activity 对象后),onCreate() 生命周期方法会被调用一次。在 onCreate() 执行后,Activity 被认为是已创建的。

  1. MainActivity.kt 的顶层,在类声明 class MainActivity 之上添加以下常量。

一个好的约定是在您的文件中声明一个 TAG 常量,因为它的值不会更改。

要将其标记为编译时常量,请在声明变量时使用 const。编译时常量是在编译期间已知的值。

private const val TAG = "MainActivity"
  1. onCreate() 方法中,在对 super.onCreate() 的调用之后,添加以下行
Log.d(TAG, "onCreate Called")
  1. 如有必要,导入 Log 类(按 Alt+Enter 或 Mac 上的 Option+Enter,然后选择 导入)。如果您启用了自动导入,则此操作应会自动完成。
import android.util.Log

Log 类将消息写入 LogcatLogcat 是用于记录消息的控制台。此处会显示 Android 关于您的应用的消息,包括您使用 Log.d() 方法或其他 Log 类方法显式发送到日志的消息。

Log 指令有三个重要方面

  • 日志消息的**优先级**,即消息的重要性。在本例中,Log.v() 记录详细消息。Log.d() 方法写入调试消息。 Log 类中的其他方法包括 Log.i() 用于信息消息,Log.w() 用于警告,以及 Log.e() 用于错误消息。
  • 日志tag(第一个参数),在本例中为"MainActivity"。tag 是一个字符串,可让你更轻松地在 Logcat 中找到你的日志消息。tag 通常是类的名称。
  • 实际的日志消息,称为msg(第二个参数),是一个短字符串,在本例中为"onCreate Called"

a4ff4aa74384ff6.png

  1. 编译并运行 Dessert Clicker 应用。点击甜点时,你不会在应用中看到任何行为差异。在 Android Studio 中,点击屏幕底部的**Logcat**选项卡。

cedcce52592c6665.png

  1. 在**Logcat**窗口中,在搜索字段中输入tag:MainActivity

37080c4e00561b0.png

Logcat 可能包含许多消息,其中大多数对你来说都没有用。你可以通过多种方式过滤 Logcat 条目,但搜索是最简单的。因为你在代码中使用了MainActivity作为日志 tag,所以可以使用该 tag 过滤日志。你的日志消息包括日期和时间、你的日志 tag、包的名称(com.example.dessertclicker)以及实际的消息。由于此消息出现在日志中,因此你知道onCreate()已执行。

步骤 2:实现onStart()方法

onStart()生命周期方法在onCreate()之后立即调用。在onStart()运行后,你的活动将在屏幕上可见。与仅调用一次以初始化你的活动的onCreate()不同,onStart()可以在你的活动生命周期中被系统多次调用。

a357d2291de472d9.png

请注意,onStart()与相应的onStop()生命周期方法配对。如果用户启动你的应用,然后返回到设备的主屏幕,则活动将停止,并且不再在屏幕上可见。

  1. 在 Android Studio 中,在MainActivity.kt打开且光标位于MainActivity类中时,选择**代码 > 重写方法...**或按Control+O。将出现一个对话框,其中包含你可以在此类中重写的所有方法的长列表。

20c34cbad8dce892.png

  1. 开始输入onStart以搜索正确的方法。要滚动到下一个匹配项,请使用向下箭头。从列表中选择onStart(),然后点击**确定**插入样板重写代码。代码如下例所示
override fun onStart() {
    super.onStart()
}
  1. onStart()方法内部,添加一条日志消息
override fun onStart() {
    super.onStart()
    Log.d(TAG, "onStart Called")
}
  1. 编译并运行 Dessert Clicker 应用,然后打开**Logcat**窗格。
  2. 在搜索字段中输入tag:MainActivity以过滤日志。请注意,onCreate()onStart()方法都是一个接一个调用的,并且你的活动在屏幕上可见。
  3. 按设备上的**主页**按钮,然后使用最近使用的应用屏幕返回到活动。请注意,活动会从其停止的地方恢复,并保留所有相同的值,并且onStart()会第二次记录到 Logcat。还要注意,onCreate()方法不会再次调用。
2024-04-26 14:54:48.721  5386-5386  MainActivity            com.example.dessertclicker           D  onCreate Called
2024-04-26 14:54:48.756  5386-5386  MainActivity            com.example.dessertclicker           D  onStart Called
2024-04-26 14:55:41.674  5386-5386  MainActivity            com.example.dessertclicker           D  onStart Called

步骤 3:添加更多日志语句

在此步骤中,你将为所有其他生命周期方法实现日志记录。

  1. 重写MainActivity中其余的生命周期方法,并为每个方法添加日志语句,如下面的代码所示
override fun onResume() {
    super.onResume()
    Log.d(TAG, "onResume Called")
}

override fun onRestart() {
    super.onRestart()
    Log.d(TAG, "onRestart Called")
}

override fun onPause() {
    super.onPause()
    Log.d(TAG, "onPause Called")
}

override fun onStop() {
    super.onStop()
    Log.d(TAG, "onStop Called")
}

override fun onDestroy() {
    super.onDestroy()
    Log.d(TAG, "onDestroy Called")
}
  1. 再次编译并运行 Dessert Clicker,并检查 Logcat。

请注意,这次除了onCreate()onStart()之外,还有一个onResume()生命周期回调的日志消息。

2024-04-26 14:56:48.684  5484-5484  MainActivity            com.example.dessertclicker           D  onCreate Called
2024-04-26 14:56:48.709  5484-5484  MainActivity            com.example.dessertclicker           D  onStart Called
2024-04-26 14:56:48.713  5484-5484  MainActivity            com.example.dessertclicker           D  onResume Called

当活动从头开始时,你将看到所有这三个生命周期回调按顺序调用

  • onCreate(),当系统创建应用时。
  • onStart()使应用在屏幕上可见,但用户尚无法与之交互。
  • onResume()将应用带到前台,用户现在可以与之交互。

尽管名称如此,但即使没有要恢复的内容,onResume()方法也会在启动时被调用。

The Activity Lifecycle scheme

4. 探索生命周期用例

现在你已为 Dessert Clicker 应用设置了日志记录,你就可以开始使用该应用并探索如何触发生命周期回调了。

用例 1:打开和关闭活动

你从最基本的用例开始,即首次启动你的应用,然后关闭应用。

  1. 编译并运行 Dessert Clicker 应用(如果尚未运行)。如你所见,当活动首次启动时,将调用onCreate()onStart()onResume()回调。
2024-04-26 14:56:48.684  5484-5484  MainActivity            com.example.dessertclicker           D  onCreate Called
2024-04-26 14:56:48.709  5484-5484  MainActivity            com.example.dessertclicker           D  onStart Called
2024-04-26 14:56:48.713  5484-5484  MainActivity            com.example.dessertclicker           D  onResume Called
  1. 点击纸杯蛋糕几次。
  2. 点击设备上的**后退**按钮。

在 Logcat 中注意,onPause()onStop()按此顺序调用。

2024-04-26 14:58:19.984  5484-5484  MainActivity            com.example.dessertclicker           D  onPause Called
2024-04-26 14:58:20.491  5484-5484  MainActivity            com.example.dessertclicker           D  onStop Called
2024-04-26 14:58:20.517  5484-5484  MainActivity            com.example.dessertclicker           D  onDestroy Called

在本例中,使用**后退**按钮会导致活动(以及应用)从屏幕上移除并移至活动堆栈的后面。

如果你的代码手动调用活动的finish()方法或用户强制退出应用,则 Android 操作系统可能会关闭你的活动。例如,用户可以在最近使用的应用屏幕中强制退出或关闭应用。如果你的应用长时间未出现在屏幕上,操作系统也可能会自行关闭你的活动。Android 这样做是为了节省电池电量并回收应用正在使用的资源,以便其他应用可以使用这些资源。这些只是 Android 系统销毁你的活动的一些示例。在 Android 系统在未提供警告的情况下销毁你的活动时,还有其他一些情况。

用例 2:从活动导航到活动并返回

现在你已启动并关闭应用,你已看到活动首次创建时的大多数生命周期状态。你还在活动关闭时经历的大多数生命周期状态中看到了大多数。但是,当用户与他们的 Android 设备交互时,他们会在应用之间切换、返回主页、启动新应用以及处理其他活动的干扰(如电话呼叫)。

你的活动不会在用户每次从该活动导航离开时都完全关闭

  • 当你的活动不再在屏幕上可见时,其状态称为将活动置于后台。与此相反的是,当活动处于前台或屏幕上时。
  • 当用户返回到你的应用时,将重新启动该活动并再次变得可见。应用的生命周期的这一部分称为应用的可见生命周期。

当你的应用处于后台时,通常不应积极运行,以节省系统资源和电池电量。你可以使用Activity生命周期及其回调来了解你的应用何时移至后台,以便你可以暂停任何正在进行的操作。然后,在你的应用进入前台时重新启动操作。

在此步骤中,你将查看应用进入后台并再次返回前台时的活动生命周期。

  1. 在 Dessert Clicker 应用运行时,点击纸杯蛋糕几次。
  2. 按设备上的**主页**按钮,并在 Android Studio 中观察 Logcat。返回主屏幕会将你的应用置于后台,而不是完全关闭应用。请注意,将调用onPause()onStop()方法。
2024-04-26 15:00:04.905  5590-5590  MainActivity            com.example.dessertclicker           D  onPause Called
2024-04-26 15:00:05.430  5590-5590  MainActivity            com.example.dessertclicker           D  onStop Called

调用onPause()时,应用将不再具有焦点。在onStop()之后,应用将不再在屏幕上可见。尽管活动已停止,但Activity对象仍保留在后台内存中。Android 操作系统尚未销毁活动。用户可能会返回到应用,因此 Android 会保留你的活动资源。

c470ee28ab7f8a1a.png

  1. 使用最近使用的应用屏幕返回到应用。在模拟器上,可以通过下图所示的方形系统按钮访问最近使用的应用屏幕。

在 Logcat 中注意,活动将使用onRestart()onStart()重新启动,然后使用onResume()恢复。

bc156252d977e5ae.png

2024-04-26 15:00:39.371  5590-5590  MainActivity            com.example.dessertclicker           D  onRestart Called
2024-04-26 15:00:39.372  5590-5590  MainActivity            com.example.dessertclicker           D  onStart Called
2024-04-26 15:00:39.374  5590-5590  MainActivity            com.example.dessertclicker           D  onResume Called

当活动返回到前台时,onCreate()方法不会再次调用。活动对象未被销毁,因此无需再次创建。代替onCreate(),将调用onRestart()方法。请注意,这次当活动返回到前台时,**已售甜点**数量将保留。

  1. 至少启动一个除 Dessert Clicker 之外的应用,以便设备在其最近使用的应用屏幕中有一些应用。
  2. 调出最近使用的应用屏幕并打开另一个最近的活动。然后返回最近使用的应用,并将 Dessert Clicker 带回前台。

请注意,在此处,你将看到与按**主页**按钮时相同的 Logcat 回调。onPause()onStop()在应用进入后台时调用,然后在应用返回时调用onRestart()onStart()onResume()

当应用停止并转到后台,或当应用重启并返回前台时,会调用这些方法。如果需要在这些情况下在应用中执行某些操作,则覆盖相关的生命周期回调方法。

用例 3:部分隐藏活动

您已经了解到,当应用启动并调用 onStart() 时,应用会在屏幕上可见。当调用 onResume() 时,应用会获得用户焦点,即用户可以与应用交互。应用完全显示在屏幕上并具有用户焦点的生命周期部分称为前台生命周期

当应用转到后台时,在 onPause() 后会失去焦点,并且在 onStop() 后应用不再可见。

焦点和可见性之间的区别很重要。活动可以在屏幕上部分可见,但没有用户焦点。在此步骤中,您将查看活动部分可见但没有用户焦点的其中一个案例。

  1. 在 Dessert Clicker 应用运行时,点击屏幕右上角的共享按钮。

共享活动显示在屏幕下半部分,但活动在上半部分仍然可见。

677c190d94e57447.pngca6285cbbe3801cf.png

  1. 检查 Logcat 并注意只调用了 onPause()
2024-04-26 15:01:49.535  5590-5590  MainActivity            com.example.dessertclicker           D  onPause Called

在此用例中,不会调用 onStop(),因为活动仍然部分可见。但活动没有用户焦点,用户无法与其交互——前台的“共享”活动具有用户焦点。

为什么这种差异很重要?仅使用 onPause() 中断通常持续时间很短,然后返回您的活动或导航到另一个活动或应用。通常,您需要继续更新 UI,以便应用的其余部分不会看起来像冻结了。

onPause() 中运行的任何代码都会阻止其他内容显示,因此请保持 onPause() 中的代码简洁。例如,如果来电,则 onPause() 中的代码可能会延迟来电通知。

  1. 点击共享对话框外部以返回应用,并注意调用了 onResume()

onResume()onPause() 都与焦点有关。当活动获得焦点时,会调用 onResume() 方法;当活动失去焦点时,会调用 onPause() 方法。

5. 探索配置更改

在管理活动生命周期时,还有另一个需要理解的重要情况:配置更改如何影响活动的生命周期。

当设备状态发生根本性变化时,就会发生配置更改,此时系统解决更改的最简单方法是完全关闭并重建活动。例如,如果用户更改设备语言,则整个布局可能需要更改以适应不同的文本方向和字符串长度。如果用户将设备插入扩展坞或添加物理键盘,则应用布局可能需要利用不同的显示尺寸或布局。如果设备方向发生变化(例如,设备从纵向旋转到横向或反向旋转),则布局可能需要更改以适应新的方向。让我们看看应用在此场景中的行为。

最后一个要演示的生命周期回调是 onDestroy(),它在 onStop() 后调用。它在活动被销毁之前调用。这可能发生在应用的代码调用 finish() 时,或者系统需要由于配置更改而销毁并重新创建活动时。

配置更改导致调用 onDestroy()

屏幕旋转是导致活动关闭并重新启动的一种配置更改类型。要模拟此配置更改并检查其影响,请完成以下步骤

  1. 编译并运行您的应用。
  2. 确保模拟器中的屏幕旋转锁定已禁用。
  3. 将设备或模拟器旋转到横向模式。您可以使用旋转按钮向左或向右旋转模拟器。
  4. 检查 Logcat 并了解,当活动关闭时,它会按顺序调用 onPause()onStop()onDestroy()
2024-04-26 15:03:32.183  5716-5716  MainActivity            com.example.dessertclicker           D  onPause Called
2024-04-26 15:03:32.185  5716-5716  MainActivity            com.example.dessertclicker           D  onStop Called
2024-04-26 15:03:32.205  5716-5716  MainActivity            com.example.dessertclicker           D  onDestroy Called

设备旋转时数据丢失

  1. 编译并运行您的应用并打开 Logcat。
  2. 点击纸杯蛋糕几次,并注意已售甜点和总收入不为零。
  3. 确保模拟器中的屏幕旋转锁定已禁用。
  4. 将设备或模拟器旋转到横向模式。您可以使用旋转按钮向左或向右旋转模拟器。

11c9d83a11651608.png

  1. 检查 Logcat 中的输出。将输出过滤到 MainActivity 上。
2024-04-26 15:04:29.356  5809-5809  MainActivity            com.example.dessertclicker           D  onCreate Called
2024-04-26 15:04:29.378  5809-5809  MainActivity            com.example.dessertclicker           D  onStart Called
2024-04-26 15:04:29.382  5809-5809  MainActivity            com.example.dessertclicker           D  onResume Called
2024-04-26 15:06:52.168  5809-5809  MainActivity            com.example.dessertclicker           D  onPause Called
2024-04-26 15:06:52.183  5809-5809  MainActivity            com.example.dessertclicker           D  onStop Called
2024-04-26 15:06:52.219  5809-5809  MainActivity            com.example.dessertclicker           D  onDestroy Called
2024-04-26 15:06:52.302  5809-5809  MainActivity            com.example.dessertclicker           D  onCreate Called
2024-04-26 15:06:52.308  5809-5809  MainActivity            com.example.dessertclicker           D  onStart Called
2024-04-26 15:06:52.312  5809-5809  MainActivity            com.example.dessertclicker           D  onResume Called

请注意,当设备或模拟器旋转屏幕时,系统会调用所有生命周期回调以关闭活动。然后,在重新创建活动时,系统会调用所有生命周期回调以启动活动。

当设备旋转且活动关闭并重新创建时,活动会以默认值重新启动——甜点图片、已售甜点数和总收入重置为零。

要了解为什么这些值会被重置以及如何更正它们,您需要了解可组合项的生命周期以及它如何知道观察和保留其状态。

可组合项的生命周期

应用的 UI 最初是通过在称为组合的过程中运行可组合函数构建的。

当应用的状态发生变化时,会安排重新组合。重新组合是指 Compose 重新执行状态可能已更改的可组合函数并创建更新的 UI。组合会更新以反映这些更改。

创建或更新组合的唯一方法是通过其初始组合和后续重新组合。

可组合函数有自己的生命周期,它独立于 Activity 生命周期。其生命周期由以下事件组成:进入组合、重新组合 0 次或多次,然后离开组合。

为了让 Compose 跟踪并触发重新组合,它需要知道何时状态发生了变化。要指示 Compose 跟踪对象的 state,该对象需要是 StateMutableState 类型。State 类型是不可变的,只能读取。 MutableState 类型是可变的,允许读取和写入。

您已经在之前的 codelab 中的 柠檬水应用小费计算器应用 中看到并使用了 MutableState

要创建可变变量 revenue,您需要使用 mutableStateOf 声明它。0 是其初始默认值。

var revenue = mutableStateOf(0)

虽然这足以让 Compose 在 revenue 值发生变化时触发重新组合,但它不足以保留其更新后的值。每次重新执行可组合函数时,它都会将 revenue 值重新初始化为其初始默认值 0

要指示 Compose 在重新组合期间保留和重用其值,您需要使用 remember API 声明它。

var revenue by remember { mutableStateOf(0) }

如果 revenue 的值发生变化,Compose 会安排所有读取此值的可组合函数进行重新组合。

虽然 Compose 在重新组合期间会记住 revenue 状态,但在配置更改期间它不会保留此状态。为了让 Compose 在配置更改期间保留状态,您必须使用 rememberSaveable

如需更多练习和信息,请参阅 Compose 中的状态简介 codelab。

使用 rememberSaveable 保存跨配置更改的值

如果 Android 操作系统销毁并重新创建活动,则可以使用 rememberSaveable 函数保存所需的值。

要保存重新组合期间的值,您需要使用 remember。使用 rememberSaveable 保存重新组合和配置更改期间的值。

使用 rememberSaveable 保存值可确保在恢复活动时(如果需要)可以使用该值。

  1. MainActivity 中,将当前使用 remember 的五个变量组更新为 rememberSaveable
var revenue by remember { mutableStateOf(0) }
...
var currentDessertImageId by remember {
    mutableStateOf(desserts[currentDessertIndex].imageId)
}
var revenue by rememberSaveable { mutableStateOf(0) }
...
var currentDessertImageId by rememberSaveable {
    mutableStateOf(desserts[currentDessertIndex].imageId)
}
  1. 编译并运行您的应用。
  2. 点击纸杯蛋糕几次,并注意已售甜点和总收入不为零。
  3. 将设备或模拟器旋转到横向模式。
  4. 观察在活动销毁并重新创建后,甜点图片、已售甜点和总收入是否恢复到其先前值。

6. 解决方案代码

7. 总结

活动生命周期

  • 活动生命周期是一组活动转换的状态。活动生命周期从 Android 操作系统首次创建活动开始,到操作系统销毁活动结束。
  • 当用户在活动之间导航,以及在应用内部和外部导航时,每个活动都会在活动生命周期中在状态之间移动。

  • 活动生命周期中的每个状态都对应一个回调方法,您可以在 Activity 类中重写该方法。核心生命周期方法集包括:onCreate()onRestart()onStart()onResume()onPause()onStop()onDestroy()
  • 要添加在活动转换到生命周期状态时发生的行为,请重写该状态的回调方法。
  • 要在 Android Studio 中向您的类添加骨架重写方法,请选择**代码 > 重写方法...**或按 Control+O

使用 Log 进行日志记录

  • Android 日志记录 API,特别是 Log 类,使您能够编写将在 Android Studio 中的 Logcat 中显示的简短消息。
  • 使用 Log.d() 写入调试消息。此方法采用两个参数:日志标签(通常是类的名称)和日志消息(一个简短的字符串)。
  • 使用 Android Studio 中的**Logcat**窗口查看系统日志,包括您编写的消息。

配置更改

  • 当设备状态发生根本性变化时,就会发生配置更改,此时系统解决更改的最简单方法是销毁并重建活动。
  • 配置更改最常见的示例是用户将设备从纵向模式旋转到横向模式,或从横向模式旋转到纵向模式。当设备语言更改或用户插入硬件键盘时,也可能发生配置更改。
  • 发生配置更改时,Android 会调用所有活动生命周期的关闭回调。然后,Android 会从头开始重新启动活动,并运行所有生命周期启动回调。
  • 当 Android 由于配置更改而关闭应用时,它会使用 onCreate() 重新启动活动。
  • 要保存需要在配置更改中保留的值,请使用 rememberSaveable 声明其变量。

了解更多