Activity的生命周期详解

以下内容摘抄自作者:任玉刚所著的《Android开发艺术探索》

生命周期

Activity生命周期图

  • OnCreate
    表示Activity正在被创建。可在这个方法中做一些初始化的工作,如初始化数据initData(),加载布局界面setContentView()等等。

  • onRestart
    表示Activity正在重新启动。一般但界面从不可见变为可见时被调用。如切换到Home界面或打开新Activity后,该界面将会调用onPause()和onStop()方法,又重新回到该界面时,该方法被调用。

  • onStart
    表示Activity正在启动。此时的Activity已经可见了,但是我们还看不到,此时还无法与用户交互。

  • onResume
    表示Activity已经出现在前台,我们已经可以看的到界面了,此时可以与用户交互了。

  • onPause
    表示Activity正在停止,紧接着onStop()就会被调用。在这里可以做一些不太耗时的操作,比如存储数据,结束动画等。这个方法执行完,新Activity的onResume()方法才会执行。极端情况下,快速返回该界面会调用onResume()。

  • onStop
    表示Activity即将停止,可以执行一些相比onPause()中更复杂点的回收工作,但是与onPause()一样,不能太耗时。

  • onDestroy
    表示Activity即将被销毁,可以在这里做最后的资源释放和回收。

特殊情况说明

  • 打开新的Activity或者切换回桌面时
    回调调用顺序为onPause() -> onStop()。注意:当新打开的Activity使用透明主题时,上一个Activity没有被遮挡,仍为可见状态,将不调用onStop()方法。

  • 当Activity被系统回收后再次打开时
    生命周期将从onCreate()开始。注意:只是生命周期一样,不代表所有过程都相同。

异常情况下的生命周期

  • 资源相关的系统配置发生改变,导致Activity被杀死并重建(如旋转屏幕)
    在默认情况下,如果我们的Activity不做特殊处理,那么当系统配置发生改变后,Activity就会被销毁并重新创建,生命周期如下:
    资源配置发生改变,Activity被销毁并重新创建时的生命周期
    系统配置发生改变后,Activity被销毁,回调方法onPause()、onStop()、onDestroy()都会被相继调用。
    由于是异常状态被终止,系统会调用onSaveInstanceState()来保存当前Activity的状态。这个方法的调用时机在onStop()之前,与onPause()没有先后关系。这个方法只会出现在Activity被异常终止的情况下被调用。
    当Activity被重新创建之后,系统会调用onRestoreInstanceState(),并把onSaveInstanceState()中所保存的Bundle对象作为参数传给onRestoreInstanceState()和onCreate()方法,因此可以通过该方法判断Activity是否是被重建的。onRestoreInstanceState()调用时序在onStart()方法之后。
    除了主动保存恢复数据之外,系统还为我们自动保存恢复一些数据如:Activity的视图结构,其中包括文本框中用户输入的数据、ListView的滚动位置等。这些View相关的状态,系统都可以默认恢复。具体想知道每个View中可以恢复哪些数据,查看每个View其中的onSaveInstanceState()和onRestoreInstanceState()。
    View的保存与恢复在系统的工作流程是这样的:Activity意外终止,调用onSaveInstanceState()保存数据后,会委托Window去保存数据,接着Window会委托它上面的顶级容器去保存。顶级容器是一个ViewGroup,一般来说它很可能是DecorView。最后顶级容器再去一一通知它的子元素来保存。这是一种典型的委托思想:上层委托下层,父容器委托子元素去处理事务。

使用方法如下:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState != null) {
            String saveTest = savedInstanceState.getString("save_test");
            Log.d("MainActivity", "save_test in onCreate(): " + saveTest);
        }
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("save_test", "这里存了一部分数据");
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        String saveTest = savedInstanceState.getString("save_test");
        Log.d("MainActivity", "save_test in onRestoreInstanceState() : " + saveTest);
    }

注意:在系统异常销毁(如:旋转屏幕)时,该Activity虽被系统销毁,但有机会重新显示的情况下才会去调用onSaveInstanceState(),而正常退出,被系统正常销毁的时候是不会调用该方法的。另外还原数据有两个地方可以进行还原,一个是在onCreate()中,在这里还原时,注意要判断savedInstanceState是否为空,另一个是在onRestoreInstanceState()回调中还原,而onRestoreInstanceState()方法一旦被调用,savedInstanceState肯定是有值的,所以不用在里面做判空处理。

  • 资源内存不足导致低优先级的Activity被杀死
    我们需要先知道Activity的优先级情况,如下所示:
    (1)前台Activity。正在和用户交互的Activity,优先级最高。
    (2)可见非前台Activity。如被Dialog遮挡的Activity,位于后台,无法和用户直接交互。
    (3)后台Activity。如已经执行了onStop()回调的Activity,优先级最低。

当系统内存不足时,系统会按照以上优先级去先后杀死目标Activity所在的进程,并在后续中通过onSaveInstanceState()和onRestoreInstanceState()来存储和恢复数据。如果一个进程中没有四大组件在执行,那么这个进程很快就会被系统杀死,因此一些后台工作会放到Service中从而保证有一定的优先级,这样就不会被系统轻易的杀死。

使Activity不被重建的方法

最简单的,就是给标签内指定configChanges属性,比如不想让Activity旋转的时候重建,就添加如下属性:

android:configChanges="orientation"

如果我们想指定多个值,可以使用“|”号连接,比如这样:

android:configChanges="orientation|keyboardHidden"

还有其他配置值,具体使用可参考下图:
参考值
上面的值很多,但实际上我们在使用时,最常用的只有local、orientation和keyboardHidden这三个选项。还有注意screenSize和smallestScreenSize这两个选项,它们和编译选项有关和运行环境无关。比如:当编译环境targetSdkVersion和minSdkVersion有一个大于13时,可以这么写:

android:configChanges="orientation|screenSize

以上就是Activity的生命周期介绍,下一篇我将记录书中讲到的《Activity的启动模式》。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

建洋你是最菜的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值