如何实现Android生命周期的回调方法
Android生命周期帮助开发者了解当用户浏览应用程序时,活动会经历哪些状态。因此,我们可以在正确的时间进行适当的操作,避免崩溃和其他错误。
一个Android应用程序有一个生命周期。从用户打开和退出一个应用程序开始,它要经过各种阶段。
一个应用程序的状态可以帮助你管理用户何时打开一个活动、暂停、恢复、停止和销毁它。
回调方法管理这些状态。你可以覆盖这些方法来做一个特定的操作,给用户正确的输出。
比方说,你的应用程序在后台运行,你希望保存一些数据。在这种情况下,你必须了解活动的生命周期。这使你能够实现正确的回调来处理这种情况。
目标
在本教程中,我们将解释不同的Android应用程序生命周期回调状态。我们将讨论适用于安卓活动生命周期的所有状态。
我们将开发一个安卓应用,展示各种活动生命周期回调的发生地。这个应用程序将具有生命周期意识,以了解哪个回调正在被执行。
先决条件
要跟上进度,你应该有。
- 安装了Android Studio。
- 对Android应用开发有良好的理解。
- 关于如何运行和使用Android Studio Logcat的预先知识。
不同活动生命周期的回调
现在让我们深入讨论不同的Android应用程序的生命周期,看看我们如何实现它们。
首先,确保Android Studio正在你的电脑上运行。
然后使用empty activity 模板创建一个新项目。在本教程中,我们将使用Java来构建一个Android应用程序。因此,请确保你选择Java作为你的首选编程语言。

一个Android活动会经历六个主要的生命周期阶段或回调。它们是onCreate(),onStart(),onResume(),onPause(),onStop(), 和onDestroy() 。当一个活动进入一个新的状态时,系统会调用这些回调中的每一个。
注意,没有必要在你的Android应用程序中实现所有这些生命周期回调。作为一个开发者,你应该知道何时实现这些回调中的每一个,这取决于活动的复杂性。
下面是一个简化的图表,说明了用户是如何与活动生命周期进行交互的。

让我们讨论一下这个活动的生命周期,并在一个实际的Android应用程序中实现它们。
onCreate()
onCreate() 回调在所有的Android应用程序中是必须的。它是我们从主屏幕或意图启动一个活动时调用的第一个方法。换句话说,它是一个默认的回调,当你创建一个新的活动时,它会被自动创建。
它是开发者实现只应发生一次的活动逻辑的唯一方法,例如初始化一个ViewModel 。
Android Studio自动创建了一个名为MainActivity.java 文件的类。这个类包含一个onCreate() 回调。它在用户第一次打开应用程序时被调用。
当一个应用程序被安装在设备上时,它是在一个doesn't exist state 。这意味着活动是死的。
一旦用户打开应用程序,生命周期就开始了。该活动被带到了前台。在这种情况下,onCreate() 被立即调用以启动应用程序。它可能包含一些组件,如活动的用户界面。
下面是一个示例代码,显示了如何实现onCreate() 方法。我添加了一个Log 和一个Toast ,在本指南的后面我们将用它来读取活动的状态。
在你的MainActivity.java ,确保你的onCreate() 方法有下面的几行来打印一个Toast 和Log 消息。
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "onCreate MainActivity", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onCreate MainActivity");
}
在这个步骤中,你的活动还不可见。它一直处于这种状态,直到onCreate() 函数完成,然后它迅速地进入下一个状态。
onStart()
当一个应用程序被启动时,系统将调用一个onStart() 方法。这个回调被调用以使活动对用户可见。
下面是onStart() 的实现方式。
@Override
protected void onStart() {
Toast.makeText(this, "onStart MainActivity", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStart MainActivity");
super.onStart();
}
onStart() 在一个应用程序的生命周期中可以被调用几次。例如,当用户打开另一个活动,然后导航回上一个活动时,这个方法可以被调用。
在活动的生命周期中,onStop() 函数被调用。这意味着一些资源被释放。onStart() 方法可以被调用来初始化这些资源。
onResume()
一旦onStart() 被调用,onResume() 被立即调用。与该活动相关的每个组件都被带到前台状态。该活动现在被认为是交互式的。
@Override
protected void onResume() {
Toast.makeText(this, "onResume MainActivity", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onResume MainActivity");
super.onResume();
}
在这一点上,该活动保持在前台状态,除非应用程序发生了什么事情。这可能包括来自其他应用程序的过度(多窗口模式的应用程序)交互,如电话或当用户导航到另一个活动时。
onPause()
onPause() 在用户切换到另一个活动或多窗口模式的应用程序时被调用。此时,该活动已经失去了焦点并在后台运行。
这个回调将暂停该活动并释放该活动所消耗的一些资源。所有未被要求的操作都被暂停了。
@Override
protected void onPause() {
Toast.makeText(this, "onPause MainActivity", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onPause MainActivity");
super.onPause();
}
当onPause() 被调用时,你可能会从内存中释放一些资源。然而,请确保你在onResume() 回调期间再次初始化它们。
onPause() 是一个简短的回调,允许过渡到其他活动。所以,在这个阶段不应该执行密集的计算。这可能会延迟应用程序向其他活动的过渡,从而导致糟糕的用户体验。
onStop()
在这一点上,大部分的活动进程已经被停止。然而,该活动仍在后台运行。
这个生命周期通常发生在onPause() 方法执行后,由于用户切换到其他活动或按下Home键。
在这种情况下,它被用来释放沉重的资源,并在活动不可见时停止不需要的密集操作。
由于onPause() 是短暂的,onStop() 可以用来将数据保存到其他渠道,如数据库。
@Override
protected void onStop() {
Toast.makeText(this, "onStop MainActivity", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStop MainActivity");
super.onStop();
}
注意:在这个时候,这个活动还没有被销毁。活动实例被保存在一个回栈中。这意味着所有陈述仍然是活动的,包括视图。
当用户再次打开它时,应用程序将不会重新加载所有的实例。相反,它将从内存中检索它们。这包括UI组件,如TextViews 。
onRestart()
由于活动的状态仍然存在,当用户重新启动活动时,onRestart() 方法可以被调用。这意味着该活动将回到主屏幕,用户可以继续与它的组件进行交互。
正如所讨论的,onCreate() 函数在一个活动的生命周期中只被调用一次。所以,当onRestart() 方法被执行时,活动将通过执行onStart() 然后onResume() 来恢复。
@Override
protected void onRestart() {
Toast.makeText(this, "onRestart MainActivity", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onRestart MainActivity");
super.onRestart();
}
onDestroy()
这是活动被停止时将收到的最后一个回调。
当配置状态(如屏幕旋转或语言设置)发生变化时,该方法被调用。Android系统将销毁该活动,然后用设定的配置重新创建它。
@Override
protected void onDestroy() {
Toast.makeText(this, "onDestroy MainActivity", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onDestroy MainActivity");
super.onDestroy();
}
测试该活动的生命周期
我们将执行这个应用程序,并阅读我们的Logcat消息,看看这些不同的方法是如何执行的。在这一点上,你的MainActivity.java 应该有以下代码。

为了测试这个应用程序,我们将添加另一个活动,这样我们就可以在这些方法从A点变化到B点时读取它们。
在Android Studio中,创建另一个empty 活动并将其称为Activity2.java 我们将添加与MainActivity.java 文件中相同的代码。然而,我们将改变Toast 和Log 的信息,如下所示。
public class Activity2 extends AppCompatActivity {
private static final String TAG = "Activity2";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
Toast.makeText(this, "onCreate Activity2", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onCreate Activity2");
}
@Override
protected void onStart() {
super.onStart();
Toast.makeText(this, "onStart Activity2", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStart Activity2");
}
@Override
protected void onRestart() {
super.onRestart();
Toast.makeText(this, "onRestart Activity2", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onRestart Activity2");
}
@Override
protected void onResume() {
super.onResume();
Toast.makeText(this, "onResume Activity2", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onResume Activity2");
}
@Override
protected void onPause() {
super.onPause();
Toast.makeText(this, "onPause Activity2", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onPause Activity2");
}
@Override
protected void onStop() {
super.onStop();
Toast.makeText(this, "onStop Activity2", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStop Activity2");
}
@Override
protected void onDestroy() {
super.onDestroy();
Toast.makeText(this, "onDestroy Activity2", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onDestroy Activity2");
}
}
在你的MainActivity中,添加以下方法来帮助我们在活动之间进行导航。
public void gotoActivity2(View view) {
Intent intent = new Intent(this, Activity2.class);
startActivity(intent);
}
上面的意图将帮助我们执行并导航到Activity2。为了执行这个方法,我们将在activity_main.xml ,如下图所示,添加一个按钮。
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Watch the Log in Android Studio when you run the application"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.056" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="52dp"
android:layout_marginEnd="50dp"
android:layout_marginStart="50dp"
android:layout_weight="50"
android:onClick="gotoActivity2"
android:text="go to Activity2"
app:layout_constraintTop_toBottomOf="@+id/text"
tools:layout_editor_absoluteX="15dp" />
这就是该应用程序在你的安卓设备上应该有的样子。

在运行这个应用程序之前,确保你在Android Studio中打开Logcat窗口。

应用程序启动后,立即按顺序执行以下方法。

该应用程序开始执行onCreate() 功能。在这个阶段,应用程序的组件还不可见。
然后,onStart() 方法被调用,接着是onResume() 。在这个生命周期中,用户可以与UI组件互动。
现在让我们通过点击go-to Activity2 按钮来导航到activity2 。
此刻,Activity2 正在阻止MainActivity 。这意味着MainActivity 将使用onPause() 的回调来暂停。这一点在下面被强调。

它表明当用户切换到Activity2 ,MainActivity 被暂停。在这一点上,MainActivity 将被保存在一个回栈中。
当Activity2 被带到前台时,onStop() 也将被调用到Mainctivity 。这是因为Android系统正在释放任何MainActivity 不使用的资源。

请注意,MainActivity并没有被销毁。这意味着它的状态被保存在内存中,我们可以检索到它们。要做到这一点,请导航回上一个活动,并观察Logcat消息。

你可以看到,这里有三个方法被执行。onRestart(),onStart(), 和onResume() 。
当你back press ,这意味着你正在退出活动,回调将执行,如下所示。

正如你所看到的,当退出应用程序时,onDestroy() 不被首先调用。该活动仍然遵循其生命周期。
结论
作为一个开发者,你应该明智地选择当某个方法或回调被执行时要执行什么。你最终可能不会在一个应用程序中使用所有这些回调。