荐 Android学习之详解Activity的生命周期
Activity
Activity作为Android的四大组件之一,可见其地位非同寻常,官网介绍:
移动应用体验与桌面体验的不同之处在于,用户与应用的互动并不总是在同一位置开始,而是经常以不确定的方式开始。例如,如果您从主屏幕打开电子邮件应用,可能会看到电子邮件列表,如果您通过社交媒体应用启动电子邮件应用,则可能会直接进入电子邮件应用的邮件撰写界面。
Activity类的目的就是促进这种范式的实现。当一个应用调用另一个应用时,调用方应用会调用另一个应用中的 Activity,而不是整个应用。通过这种方式,Activity 充当了应用与用户互动的入口点。您可以将 Activity 实现为Activity类的子类。
下面是关于Activity类的文档说明:
更多详情可见官方API文档:Activity类
Activity类是 Android 应用的关键组件,而 Activity 的启动和组合方式则是该平台应用模型的基本组成部分。在编程范式中,应用是通过main()
方法启动的,而 Android 系统与此不同,它会调用与其生命周期特定阶段相对应的特定回调方法来启动 Activity实例中的代码。
扩展:Activity / ActionBarActivity / AppCompatActivity的区别:
Activity
是大佬就不用说啦,后面这两个(ActionBarActivity / AppCompatActivity)
都是为了低版本兼容而提出来的,它们都在v7包下, ActionBarActivity已被废弃,从名字就知道,ActionBarActivity在5.0后,被Google弃用了,AppCompatActivity
其实是ActionBarActivity
的替代,默认带标题。而我们现在在Android Studio创建一个Activity默认继承的会是:AppCompatActivity
! 当然你也可以改成Activity
,没什么影响的,看个人喜好。
在开发Android应用过程中,通常Activity(活动)是与用户交互的接口,它提供了一个用户完成相关操作的窗口。当我们在开发中创建Activity后,通过调用setContentView(View)方法来给该Activity指定一个布局界面,而这个界面就是提供给用户交互的接口。Android系统中是通过Activity栈的方式来管理Activity的,而Activity自身则是通过生命周期的方法来管理自己的创建与销毁,So,下面我将讲一下关于Activity的生命周期。
Activity的生命周期
先上图,官方给出的Activity 生命周期的简化图:
当用户浏览、退出和返回到Android应用时,应用中的 Activity 实例会在其生命周期的不同状态间转换。Activity 类会提供许多回调,这些回调会让 Activity 知晓某个状态已经更改:系统正在创建、停止或恢复某个 Activity,或者正在销毁该 Activity 所在的进程。
为了在 Activity 生命周期的各个阶段之间导航转换,Activity 类提供六个核心回调:
onCreate()
、onStart()
、onResume()
、onPause()
、onStop()
和onDestroy()
。当 Activity 进入新状态时,系统会调用其中每个回调。
-
onCreate()
代码必须实现此回调
,它会在系统首次创建 Activity 时触发。Activity 会在创建后进入“已创建”状态。它是生命周期第一个调用的方法,在该方法中做一些初始化的操作,如通过setContentView设置界面布局的资源,初始化所需要的组件信息等,这些基本应用启动逻辑在 Activity 的整个生命周期中只应发生一次。 -
onStart()
当上面的onCreate()
方法执行完成之后,Activity会 进入“已开始”状态,系统会调用此回调。表示Activity正在启动,这是在 Activity 即将对用户可见之前调用的,此时的Activity已处于可见状态,只是还没有在前台显示,因此无法与用户进行交互。onStart()
方法会非常快速地完成,Activity 不会一直处于“已开始”状态。一旦此回调结束,Activity 便会进入“已恢复”状态,系统将调用onResume()
方法。 -
onResume()
Activity 会在进入“已恢复”状态时来到前台,然后系统调用onResume()
回调,此时Activity 处于 Activity 堆栈的顶层,也可以说明Activity已在前台可见,并具有用户输入焦点,可与用户交互了。这是应用与用户互动的状态,应用会一直保持这种状态,直到某些事件发生,让焦点远离应用。此类事件包括接到来电、用户导航到另一个 Activity,或设备屏幕关闭。
当Activity停止后(onPause()
方法或者onStop()
方法被调用),重新回到前台时也会调用onResume()
方法,因此我们也可以在onResume()
方法中初始化一些资源,比如重新初始化
在onPause()
或者onStop()
方法中释放的资源
。 -
onPause()
系统将此方法视为用户将要离开 Activity 的第一个标志(尽管这并不总是意味着 Activity 会被销毁)。此方法表示 Activity 不再位于前台(尽管在用户处于多窗口模式时 Activity 仍然可见)。
在 Android 7.0(API 级别 24)或更高版本中,有多个应用在多窗口模式下运行。无论何时,都只有一个应用(窗口)可以拥有焦点,因此系统会暂停所有其他应用。onPause()
执行非常简单,而且不一定要有足够的时间来执行保存操作。因此,不应使用onPause()
来保存应用或用户数据、进行网络调用或执行数据库事务。因为在该方法完成之前,此类工作可能无法完成。相反,应在onStop()
期间执行高负载的关闭操作。 正常情况下,onStop()
方法会紧接着被回调的,但是有一种极端情况,onPause()
方法执行后直接执行了onResume()
方法,这可能是用户操作使当前Activity退居后台后,又迅速地再次回到到当前的Activity,此时onResume()
方法就会被回调。 -
onStop()
如果 Activity 不再对用户可见,说明其已进入“已停止”状态,因此系统将调用onStop()
回调。在onStop()
方法中,应用应释放或调整在应用对用户不可见时的无用资源。例如,应用可以暂停动画效果,或从精确位置更新切换到粗略位置更新。使用onStop()
而非onPause()
可确保与界面相关的工作继续进行,即使用户在多窗口模式下查看您的 Activity 也能如此。 还可以 执行 CPU 相对密集的关闭操作。例如,如果无法找到更合适的时机来将信息保存到数据库,可以在onStop()
期间执行此操作。
进入“已停止”状态后,Activity 要么返回与用户互动,要么结束运行并消失。如果 Activity 返回,系统将调用onRestart()
。如果 Activity 结束运行,系统将调用onDestroy()
。
备注:
AlertDialog和PopWindow是不会触发上述
onPause()
和onStop()
两个回调方法的。
-
onRestart()
在Activity被停止后再次启动时调用(即屏幕熄灭后再次回到app,按下home键后再次回到app),而后面会调用onStart()
方法。 -
onDestroy()
销毁 Activity 之前,系统会先调用onDestroy()
。系统调用此回调的原因:
1、Activity 即将结束(由于用户彻底关闭 Activity 或由于系统为 Activity 调用 finish())
2、由于配置变更(例如设备旋转或多窗口模式),系统暂时销毁 Activity
可以使用 isFinishing() 方法区分这两种情况。
如果 Activity 即将结束,onDestroy()
是 Activity 收到的最后一个生命周期回调。如果由于配置变更而调用onDestroy()
,系统会立即新建 Activity 实例,然后在新配置中为新实例调用onCreate()
。onDestroy()
回调应释放先前的回调(例如onStop()
)尚未释放的所有资源。
注意:上面这些都是回调方法,我们不能够去调用,我们能做的只是重写方法里面的内容,什么时候去调用是由Activity所决定的。我们可以调用finish()方法,它可用于关闭某个Activity。
代码验证
第一个Activity:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Main";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = findViewById(R.id.bt_main2);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, Main2Activity.class));
}
});
Log.d(TAG, "onCreate: ------> MainActivity进入“已创建”状态!");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart: ------> “已停止”状态的MainActivity即将重启!");
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart: ------> MainActivity进入“已开始”状态!");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ------> MainActivity进入“应用与用户互动”状态!");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: ------> MainActivity进入“已暂停”状态!");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: ------> MainActivity进入“已停止”状态!");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ------> MainActivity进入“已销毁”状态!");
}
}
第二个Activity:
public class Main2Activity extends AppCompatActivity {
private static final String TAG = "Main";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Log.d(TAG, "onCreate: ------> Main2Activity进入“已创建”状态!");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart: ------> “已停止”状态的Main2Activity即将重启!");
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart: ------> Main2Activity进入“已开始”状态!");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ------> Main2Activity进入“应用与用户互动”状态!");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: ------> Main2Activity进入“已暂停”状态!");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: ------> Main2Activity进入“已停止”状态!");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ------> Main2Activity进入“已销毁”状态!");
}
}
验证结果:
-
正常进入Activity,log日志输出:
-
点击Back键正常退出Activity,log日志输出:
-
正常进入Activity,点击Home键返回主界面,log日志输出:
-
点完Home键,重新进入Activity,log日志输出:
-
正常进入Activity,启动另外一个Activity2,log日志输出:
-
进入另外一个Activity2后,点击Back键再次回到Activity,log日志输出:
-
正常进入Activity,进入分屏模式,且失去焦点时,log日志输出:
-
Activity退出分屏模式,获取焦点进入全屏模式,log日志输出:
结论:
当Activity启动时,会依次调用onCreate()
,onStart()
,onResume()
,也就是Activity已在前台可见,并具有用户输入焦点,可与用户交互了,而当Activity退到后台时(不可见,点击Home或者被新的Activity完全覆盖),onPause()
和onStop()
会依次被调用。当Activity重新回到前台(从手机主屏幕回到原Activity或者被覆盖后又回到原Activity)时,onRestart()
,onStart()
,onResume()
会依次被调用。当Activity退出&销毁时(点击Back键),onPause()
,onStop()
,onDestroy()
会依次被调用,到此Activity的整个生命周期方法回调完成。
参考文章:
Android开发者:Activity简介 https://developer.android.google.cn/guide/components/activities/intro-activities
4.1.1 Activity初学乍练 https://www.runoob.com/w3cnote/android-tutorial-activity.html
Android之Activity生命周期浅析(一) https://blog.csdn.net/javazejian/article/details/51932554
本文地址:https://blog.csdn.net/qq_36270361/article/details/107141162
推荐阅读
-
两分钟让你彻底明白Android Activity生命周期的详解(图文介绍)
-
React Native学习之Android的返回键BackAndroid详解
-
两分钟让你彻底明白Android Activity生命周期的详解(图文介绍)
-
荐 Android学习之详解Activity的生命周期
-
Android Activity生命周期和堆栈管理的详解
-
黑马Android76期学习笔记01基础--day06--拨打电话、Intent、activity生命周期,任务栈、activity的四种启动模式
-
Android开发中Activity的生命周期及加载模式详解
-
Android开发中Activity的生命周期及加载模式详解
-
Android开发之activity的生命周期详解
-
Android中的Activity生命周期详解_PHP教程