【Android Activity】Activity的生命周期

知识点

在这里插入图片描述

一、Activity的生命周期

1、 生命周期回调

onCreate:表示Activity正在被创建。生命周期的第一个方法,当打开一个activity时首先回调这个方法。在这个方法中一般做一些初始化工作,例如加载界面布局资源(setContentView)、数据初始化(findviewbyid)

onRestart : 表示Activity正在被重新启动。当前activity从不可见变为可见状态时这个方法就会回调。一般是用户行为导致,比如用户摁home键回到桌面,当用户再次回到本activity时,当前activity 走 onRestart->onStart->onResume

onStart :表示activity正在被启动。activity可见,未出现在前台。可以理解为activity已经显示出来了,但是我们看不到,不能与之交互。

onResume :表示activity已经可见,并且出现在前台,可以与用户进行交互。例如activity上有Button,此时我们就可以进行点击了。

onPause:表示activity正在停止,接着很快执行onStop。注意极端情况下,本Activity跳转其他activity后快速的回到当前activity时,当前activity的生命周期:onPause->onResume
但是这个“快速回到”要很快,一般情况下都是onPause->onStop->onRestart->onStart->onResume。这里不能做太耗时操作,可以做一些数据存储,动画停止工作。

onStop:表示activity即将停止,可以做一些回收工作。但是不能太耗时。

onDestroy :activity即将被销毁 ,activity生命周期最后一个回调,这里可以做一些回收工作,资源释放。

2、Activity生命周期切换过程图解

在这里插入图片描述

3、生命周期的切换过程实践

在面试Activity的基础时两Activity切换时的生命周期执行顺序老是被考察,这里就以一个简单的栗子来实践下。

#MainActivity


public class MainActivity extends AppCompatActivity {

    public static final String TAG = "tags";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //打开Main2Activity
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, Main2Activity.class));
            }
        });
        Log.i(TAG, "onCreate:");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, "onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop: ");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, "onRestart: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
    }
}


#Main2Activity


public class Main2Activity extends AppCompatActivity {
    public static final String TAG = "tags";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2);
        Log.i(TAG, "Main2Activity onCreate:");
    }
    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, "Main2Activity onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "Main2Activity onResume: ");
    }
    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "Main2Activity onPause: ");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "Main2Activity onStop: ");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, "Main2Activity onRestart: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "Main2Activity onDestroy: ");
    }
}

(1) MainActivity 第一次启

MainActivity 经历了:onCreate->onStart->onResume

在这里插入图片描述

(2)由mainactivity跳转到Main2Activity时:
在这里插入图片描述

1、MainActivity 经历了:onPause->onStop
2、MainActivity走onPause时,新的Main2Activity会先走: Main2Activity onCreate -> Main2Activity onStart -> Main2Activity onResume 然后MainActivity 走 ->onStop
3、强调:

  • 如果此时Main2Activity 已经设置了透明主题则mainActivity是不走onStop的,只走个onPause。从MainActivity跳转到Main2Activity 我们还是可以看见mainActivity,所以验证了onPause的可见不前台。
  • 展示对话框不影响生命周期。

(3)在MainActivity时摁Home键
在这里插入图片描述

MainActivity 走onPause->onStop

(4)摁Home后再次回到MainActivity时
在这里插入图片描述

此时MainActivity走了 onRestart->onStart->onResume

(5)启动mainActivity跳转到Main2Activity,再返回到 mainActivity
在这里插入图片描述

如上:
红圈1对应启动mainActivity
红圈2对应跳转到Main2Activity
红圈3对应再返回到 mainActivity

(6)用户打开mainactivity然后摁back键

在这里插入图片描述

mainActivity走了 onPause->onStop->onDestroy

4、 生命周期小结
  • 整个生命周期来说onCreate和onDestroy 是配对的,分别代表着actiity的创建和销毁。并且只可能调用一次。
  • activity是否可见来说onStart和onStop是配对的,随着用户的操作两个生命周期可能被多次执行。
  • activity是否在前台来说onResume和onPause是配对的,随着用户的操作两个生命周期可能被多次执行。
5、 问题思考

问题1:onStart 和 onResume ,onPause 和onStop从描述上差不多对我们来说有什么实质不同?

从使用过程来讲两对的确差不多,甚至我们可以只保留一对,比如只保留onStart 、onStop。根据上面的分析我们知道,这两对接口代表不同的意义。onStart 、onStop是从是否可见的角度来回调的(前者可见后者不可见)。onResume 、onPause,是从是否前台的角度来回调的(前者前台,后者非前台)

问题2:假设当前activity为A,如果这时用户打开新的activityB,B的onResume 和A的onPause那个先执行

执行结果 A:onPause->B:onCreate->B:onStart->B:onResume->A:onStop

6、 异常情况下的生命周期

上述的摁Home键、返回键、按钮跳转页面都是正常情况下人为操作。其实Activity的生命周期还受如下因素影响,如下两个条件触发时默认情况下Activity会销毁然后重建,当然我们也可以阻止系统重建我们的activity
1、资源相关的系统配置发生改变:如横竖屏切换。
2、系统内存不足

7、资源相关配置发生改变导致Activity被杀死并重新创建

如下栗子验证了资源相关配置发生改变导致activity被销毁然后立刻自动重建。

(1)默认情况下我们打开activity
在这里插入图片描述

(2)旋转屏幕
在这里插入图片描述

在这里插入图片描述

7、异常情况下数据的存储

(1)两个方法

activity有两个回调方法onSaveInstanceState、onRestoreInstanceState。用来进行异常情况下数据的存储、恢复。
1、onSaveInstanceState(Bundle outState)

  • activity异常终止时系统会调用此方法来保存activity的状态(例如记录界面上输入框的文字、ListView滑动位置,重建时直接恢复这些状态)
  • activity异常终止时我们也可以在这个方法中添加逻辑操作,存储我们想要的信息。
  • 注意这个方法在activity正常终止是不会回调的。

2、onRestoreInstanceState(Bundle savedInstanceState)

  • 当activity异常终止重建时,系统会回调此方法,并把activity销毁时onSaveInstanceState方法所保存的Bundle 对象作为参数传递给onCreate和onRestoreInstanceState,
  • 可通过onCreate和onRestoreInstanceState方法判断activity是否被重建。因为正常情况下Activity的onCreate方法的Bundle参数为null。异常情况下Bundle才非空。

(2)异常情况下EditText 数据恢复栗子

 @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.i(TAG, "onSaveInstanceState: ");
        //存下自定义数据
        outState.putString("tom","异常下存数据 :tom");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.i(TAG, "onRestoreInstanceState: ");
        //读取存取的数据
        Log.i(TAG, " "+savedInstanceState.get("tom"));
    }

在这里插入图片描述

输入内容后点击按钮让屏幕旋转:
在这里插入图片描述
在这里插入图片描述

可以看到回调走了数据也恢复了:
1、editText输入的文字在activity销毁后重建得到恢复。
2、我们自定义的数据得到也恢复。
ps:特别注意EditText控件一定要在xml布局中设置id,否则数据不会被恢复(原因参看EditText源码,内部有处理Activity如何帮view恢复数据的)

(3)onRestoreInstanceState和onCreate中都可以收到onSaveInstanceState存的Bundle值。这两个方法有啥区别?

  • onRestoreInstanceState
    只有异常声明周期下这个回调才会被调用(onSaveInstanceState也是)一旦被调用其参数savedInstanceState一定是有值的,我们不用额外判空。
  • onCreate
    如果是正常启动Activity时,onCreate方法的参数值为空,所以要使用参数值时要额外判空。
8、系统内存不足导致低优先级的activity被杀死

这种情况我们不好模拟,但是其生命周期、数据存储、的相关方法回调和资源配置发生改变回调是完全一致的。

activity的优先级高低:

  • 前台activity
    正在和用户交互的activity,优先级最高。
  • 可见但非前台activity
    比如activity中弹出个对话框,导致activity还是可见,但是无法和用户交互了,优先级次于前台。
  • 后台activity
    已经被停止的activity,比如执行了onstop。优先级最低。

1、系统内存不足时,系统总会优先杀死低进程的activity。
2、安卓中的进程(优先级从高到低):前台>可见>服务进程 >后台进程 >空进程

9、异常情况那些case会触发activity重新创建?
属性值含义
mccSIM卡唯一标识IMSI(国际移动用户识别码)中的国家代码,由三维数组组成,中国为460,此项标识mcc代码发生改变
mncSIM卡唯一标识IMSI(国际移动用户识别码)中的运营商代码,由两位数字组成,中国移动TD系统为00,中国联通为01中国电信为03,此项标识mnc代码发生改变
locale设备的本地位置发生改变,一般指切换了系统语言
touchscreen触摸屏发生了变化,这个可以忽略,正常情况下不会发生
keyboard键盘类型发生了变化 例如,用户插入了一个外置键盘。
keyboardHidden键盘的可访问性发生改变比如用户调出键盘
navigation系统导航方式发生改变,比如采用了轨迹球导航,很难发生,可以忽略
screenLayout屏幕布局发生改变,很可能用户激活了另外一个显示设备
fontScale系统字体缩放比例发生改变,比如用户选择了一个新字号
uiMode用户界面模式发生改变,比如是否开启了夜间模式(api 8新添加)
orientation屏幕方向发生改变,这个最常用,比如旋转了手机屏幕
screenSize当屏幕的尺寸信息发生改变,当旋转设备屏幕时,屏幕尺寸会发生改变,这个选项比较特殊,他和编译选项有关,当编译选项中的minSdkVersion和targetSdkVersion均低于13时此选项不会导致activity重启,否则导致activity重启(api 13新添加)
smallestScreenSize当设备的物理屏幕尺寸信息发生改变,这个属性值和屏幕的方向没关系,仅表示实际的物理屏幕发生改变时触发,比如用户切换到外设的显示设备,和screenSize一样,当编译选项中的minSdkVersion和targetSdkVersion均低于13时此选项不会导致activity重启,否则导致activity重启(api 13新添加)
layoutDirection当布局方向发生改变,这个属性用的比较少正常情况下无法修改布局的layoutDirection(api 17新添加)

上面情况发生时activity默认会被销毁重建,最常见的就是“orientation” 横竖屏切换喽~

那么可以阻止activity重新创建吗?答案是有的:

1、在清单文件为activity指定configChanges = xxx,代表xxx模式下activity不会重新创建。
2、重写activity的onConfigurationChanged方法在activity发生xxx配置更改时onConfigurationChanged就会回调,这里我们可做一些监听工作。
ps:configChanges的属性值如上表,配置多个属性值时使用|链接即可

小结

Activity的生命周期就详细的回顾了下~

  • 9
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android中的Activity生命周期包括以下几个方法:onCreate、onStart、onResume、onPause、onStop和onDestroy。onCreate方法被调用时,表示Activity正在被创建,可以在这个方法中进行一些初始化操作。onStart方法在Activity即将变为可见状态时被调用,可以在这个方法中开始一些活动,如注册监听器等。onResume方法在Activity变为可见并且可以与用户进行交互之前被调用,可以在这个方法中开始一些动画、音乐等操作。onPause方法在Activity失去前台焦点、但仍然可见时被调用,可以在这个方法中暂停一些活动,如暂停动画、音乐等操作。onStop方法在Activity完全不可见时被调用,可以在这个方法中释放一些资源,如取消注册监听器等。onDestroy方法在Activity即将被销毁时被调用,可以在这个方法中进行一些回收工作,如释放资源。根据不同的情况,Activity生命周期的调用顺序可能有所不同,但是每个生命周期方法都有其特定的用途。例如,onPause和onResume方法通常是成对出现的,表示Activity失去前台焦点和重新获得前台焦点。总体而言,Activity生命周期的不同阶段可以用来管理资源的创建、释放和活动的状态切换等操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [【Android ActivityActivity生命周期](https://blog.csdn.net/qq_38350635/article/details/88855761)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值