前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >安卓activity生命周期_请描述activity的生命周期

安卓activity生命周期_请描述activity的生命周期

作者头像
全栈程序员站长
发布2022-09-22 21:14:37
5630
发布2022-09-22 21:14:37
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

Activity作为Android的四大组件之一,非常的重要,也是最常用的四大组件,使用Activity必须要在AndroidManifest中进行注册,那么作为Android的基础,Activity的生命周期你是否完全掌握了呢?下面就让我们来一起回顾一下Activity的生命周期吧!

首先,你需要知道 Activity的生命周期分为两种。

  1. 典型情况下的生命周期(就是我们开发中经常用到的)
  2. 异常情况下的生命周期(虽说开发中也会用到,但是并不是所有的项目都会去(需要)回调异常生命周期的方法)

所以我们先来介绍前者,因为后者出现的情况比较特殊。

  • 典型情况下的生命周期。(官网的流程图肯定是要看的,一张图包含了一个Activity从创建到销毁所经历的一切)

先总结一下有什么生命周期回调方法以及各个生命周期回调方法都是代表什么意思。

  1. onCreate:在首次创建 Activity 时调用。系统向此方法传递一个 Bundle 对象,其中包含 Activity 的上一状态,不过前提是捕获了该状态,而后会调用onStart方法。(可以在此方法中执行所有正常的静态设置 ,比如:创建视图、将数据绑定到列表等等。)
  2. onStart:在 Activity 即将对用户可见之前调用。而后如果Activity转入了前台就会调用onResume方法。 如果此时直接屏幕熄灭或者用户按下home键则会直接调用onStop方法,当然这种情况比较极端。
  3. onResume:在 Activity 即将开始与用户进行交互之前调用。 此时,Activity 处于 Activity 堆栈的顶层,并具有用户输入焦点。当跳转另一个Activity,或者退出当前Activity后会调用onPause方法。
  4. onPause:在系统即将开始继续另一个 Activity 时调用。 此方法通常用于确认对持久性数据的未保存更改、停止动画以及其他可能消耗 CPU 的内容,诸如此类。 它应该非常迅速地执行所需操作,因为它返回后,下一个 Activity 才能继续执行,所以不能执行耗时操作。而后正常情况下会调用onStop方法。但是有一种极端情况,就是如果这个时候快速让 当前Activity 返回前台,则会调用onResume方法。
  5. onStop:在 Activity 对用户不再可见时调用。如果 Activity 被销毁,或另一个 Activity(一个现有 Activity 或新 Activity)继续执行并将其覆盖,就会调用此方法。而后如果 Activity 恢复与用户的交互,则会调用 onRestart 方法,如果 Activity 被销毁,则会调用onDestroy方法。
  6. onRestart:在Activity被停止后再次启动时调用(即屏幕熄灭后再次回到app,按下home键后再次回到app),而后会调用onStart方法。
  7. onDestroy:在 Activity 被销毁前调用,这是 Activity 收到的最后调用。 当 Activity 结束(对 Activity 调用了 finish 方法),或系统为节省空间而暂时销毁该 Activity 实例时,可能会调用它。 你可以通过 isFinishing 方法区分这两种情形。

代码验证:

  • 代码
代码语言:javascript
复制
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    LogUtils.d(TAG,"onCreate ---> 创建时调用");
}

@Override
protected void onRestart() {
    super.onRestart();
    LogUtils.d(TAG,"onRestart ---> 重启时调用");
}

@Override
protected void onStart() {
    super.onStart();
    LogUtils.d(TAG,"onStart ---> 即将可见不可交互时调用");
}

@Override
protected void onResume() {
    super.onResume();
    LogUtils.d(TAG,"onResume ---> 可见可交互时调用");
}

@Override
protected void onPause() {
    super.onPause();
    LogUtils.d(TAG,"onPause ---> 即将暂停时调用");
}

@Override
protected void onStop() {
    super.onStop();
    LogUtils.d(TAG,"onStop ---> 即将停止不可见时调用");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    LogUtils.d(TAG,"onDestroy ---> 即将销毁时调用");
}
  • 验证结果

1.正常进入Activity的生命周期log日志。

代码语言:javascript
复制
V/MAIN_ACTIVITY: onCreate ---> 创建时调用
V/MAIN_ACTIVITY: onStart ---> 即将可见不可交互时调用
V/MAIN_ACTIVITY: onResume ---> 可见可交互时调用

2.点击物理返回键正常退出Activity的生命周期log日志。(长按home键退出应用不走onDestroy回调方法,但是会走onSaveInstanceState方法,后面会讲)

代码语言:javascript
复制
V/MAIN_ACTIVITY: onPause ---> 即将暂停时调用
V/MAIN_ACTIVITY: onStop ---> 即将停止不可见时调用
V/MAIN_ACTIVITY: onDestroy ---> 即将销毁时调用

3.正常进入Activity,点击home键返回手机主界面的生命周期log日志。

代码语言:javascript
复制
V/MAIN_ACTIVITY: onCreate_A ---> 创建时调用
V/MAIN_ACTIVITY: onStart_A ---> 即将可见不可交互时调用
V/MAIN_ACTIVITY: onResume_A ---> 可见可交互时调用
V/MAIN_ACTIVITY: onPause_A ---> 即将暂停时调用
V/MAIN_ACTIVITY: onStop_A ---> 即将停止不可见时调用

4.长按home键再次回到 Activity 的生命周期log日志。

代码语言:javascript
复制
V/MAIN_ACTIVITY: onRestart_A ---> 重启时调用
V/MAIN_ACTIVITY: onStart_A ---> 即将可见不可交互时调用
V/MAIN_ACTIVITY: onResume_A ---> 可见可交互时调用

5.正常进入Activity_A,启动另一个Activity_B 的生命周期log日志。

代码语言:javascript
复制
V/MAIN_ACTIVITY: onCreate_A ---> 创建时调用
V/MAIN_ACTIVITY: onStart_A ---> 即将可见不可交互时调用
V/MAIN_ACTIVITY: onResume_A ---> 可见可交互时调用
V/MAIN_ACTIVITY: onPause_A ---> 即将暂停时调用
V/MAIN_ACTIVITY: onCreate_B ---> 创建时调用
V/MAIN_ACTIVITY: onStart_B ---> 即将可见不可交互时调用
V/MAIN_ACTIVITY: onResume_B ---> 可见可交互时调用
V/MAIN_ACTIVITY: onStop_A ---> 即将停止不可见时调用

6.按下物理返回键再次回到Activity_A的生命周期log日志。

代码语言:javascript
复制
V/MAIN_ACTIVITY: onPause_B ---> 即将暂停时调用
V/MAIN_ACTIVITY: onRestart_A ---> 重启时调用
V/MAIN_ACTIVITY: onStart_A ---> 即将可见不可交互时调用
V/MAIN_ACTIVITY: onResume_A ---> 可见可交互时调用
V/MAIN_ACTIVITY: onStop_B ---> 即将停止不可见时调用
V/MAIN_ACTIVITY: onDestroy_B ---> 即将销毁时调用

总结:可以清晰地看到,Avtivity的整个生命周期是发生在 onCreate 方法 和 onDestroy 方法之间的。其中可见生命周期是发生onStart 方法和 onStop 方法之间的,也就是用户可以在界面看到Activity并且可以交互的状态。前台生命周期是发生在onResume 方法和 onPause 方法之间的,这个状态下Activity位于所有的Activity之上,并且可以和用户交互。

备注:因为如果跳转下一个Activity时系统会先调用上一个Activity的onPause方法,所以一定不能在onPause方法中进行耗时操作!

  • 异常情况下的生命周期。 (Activity被系统回收或者当前设备的配置发生了变化“例如横屏”,从而导致Activity被销毁重建,我们来看下官网流程图)

先总结一下有什么生命周期回调方法以及各个生命周期回调方法都是代表什么意思。

1.onSaveInstanceState:当系统为了恢复内存而销毁某项 Activity 时,Activity 对象也会被销毁,因此系统在继续 Activity 时根本无法让其状态保持完好,而是必须在用户返回 Activity 时重建 Activity 对象。但用户并不知道系统销毁 Activity 后又对其进行了重建,因此他们很可能认为 Activity 状态毫无变化。 在这种情况下,你可以实现onSaveInstanceState回调方法对有关 Activity 状态的信息进行保存,以确保有关 Activity 状态的重要信息得到保留。

调用时机:当用户按下HOME键时、长按HOME键,选择运行其他的程序时、按下电源按键(关闭屏幕显示)时、从activity A中启动一个新的activity时、屏幕方向切换时,例如从竖屏切换到横屏时。

2.onRestoreInstanceState 或者 onCreate:系统会先调用onSaveInstanceState方法,然后销毁 Activity。系统会向该方法传递一个Bundle 对象,你可以在其中使用putString 和 putInt 等方法以键-值对形式保存有关 Activity 状态的信息。然后,如果系统终止您的应用进程,并且用户返回您的 Activity,则系统会重建该 Activity,并将Bundle同时传递给onCreate和onRestoreInstanceState。您可以使用上述任一方法从Bundle 提取您保存的状态并恢复该 Activity 状态。如果没有状态信息需要恢复,则传递给您的Bundle是空值(如果是首次创建该 Activity,就会出现这种情况)。

解析流程图:可以看到,从Activity running开始走,Activity 重获用户焦点时可保持状态完好。恢复数据的方式跟随生命周期的不同有两种情况。

  1. 系统在销毁 Activity 后重建 Activity,Activity 必须恢复之前保存的状态。
  2. 系统停止 Activity 后继续执行 Activity,并且 Activity 状态保持完好。

代码验证:

  • 代码
代码语言:javascript
复制
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (outState != null){
        outState.putString("TEST","test");
        LogUtils.d(TAG2,"onSaveInstanceState ---> 异常销毁时调用");
    }

}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);

    if (savedInstanceState != null){
        String test = savedInstanceState.getString("TEST");
        LogUtils.d(TAG2,"onRestoreInstanceState ---> 恢复数据时调用 --> " + test);
    }
}
  • 验证结果

1.旋转手机屏幕查看log日志。

代码语言:javascript
复制
V/MAIN_ACTIVITY2: onSaveInstanceState ---> 异常销毁时调用
V/MAIN_ACTIVITY2: onRestoreInstanceState ---> 恢复数据时调用 --> test

总结:注意:onSaveInstanceState的调用时序在onStop之前,但是和onPause 的调用时序就不一定了,有可能在onPause之前或者之后。又因为无法保证系统会调用onSaveInstanceState(存在不需要保存状态的情况,例如用户使用“返回”按钮离开您的 Activity 时,因为用户的行为是在显式关闭 Activity),因此您只应利用它来记录 Activity 的瞬态(UI 的状态)切勿使用它来存储持久性数据,而应使用onPause在用户离开 Activity 后存储持久性数据,例如应保存到数据库的数据。

备注:

  1. 当 Activity 暂停或停止时(用户按下hoem键或者屏幕熄灭),Activity 的状态会得到保留。 确实如此,因为当 Activity 暂停或停止时,Activity对象仍保留在内存中 ,有关其成员和当前状态的所有信息仍处于活动状态。 因此,用户在 Activity 内所做的任何更改都会得到保留,这样一来,当 Activity 返回前台(当它“继续”)时,这些更改仍然存在,所以,即使您什么都不做,也不实现onSaveInstanceState,Activity类的 onSaveInstanceState默认实现也会恢复部分 Activity 状态。具体地讲,默认实现会为布局中的每个View 调用相应的onSaveInstanceState方法,让每个视图都能提供有关自身的应保存信息。Android 框架中几乎每个小部件都会根据需要实现此方法,以便在重建 Activity 时自动保存和恢复对 UI 所做的任何可见更改。例如,EditText 小部件保存用户输入的任何文本,CheckBox小部件保存复选框的选中或未选中状态。您只需为想要保存其状态的每个小部件提供一个唯一的 ID(通过 android:id 属性)。如果小部件没有 ID,则系统无法保存其状态。(默认情况下系统不会恢复储存成员值(变量))
  2. 你只需旋转设备,让屏幕方向发生变化,就能有效地测试您的应用的状态恢复能力。 当屏幕方向变化时,系统会销毁并重建 Activity,以便应用可供新屏幕配置使用的备用资源。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/170691.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档