Activity的生命周期

时间:2022-01-02 14:45:11

Activity的生命周期

本篇内容主要包括:

  • 正常情况下Activity的生命周期

    • Activity的生命周期图
    • 具体实例
  • 异常情况下Activity的生命周期

    • onWindowFocusChanged
    • onSaveInstanceState/onRestoreInstanceState

      • 什么情况下onSaveInstanceState会被调用?
      • Activity意外终止时,系统的数据、视图结构存储和恢复机制原理?

正常情况下Activity的生命周期

Activity的生命周期图

正常情况下,Activity会经历如下生命周期:

  1. onCreate:表示Activity正在被创建,在一个生命周期里只会调用一次,主要在这个方法中做一些初始化的工作,比如调用setContentView、初始化Activity所需数据等。
  2. onReStart:表示Activity正在重新启动,当当前Activity从不可见重新变为可见状态时会被调用,在一个生命周期里会多次调用,比如从桌面回到当前Activity或者从另一个Activity返回到当前Activity时,都会出现这种情况。
  3. onStart/onStop:表示Activity是否可见,可多次调用,这时Activity已经可见/不可见,但还没有出现在前台,还无法和用户交互。主要在onStop做一些回收工作,但不能太耗时。
  4. onResume/onPause:表示Activity是否在前台,可多次调用,这时Activity 在/不在前台并开始活动,可以和用户进行交互。通常在onPause做一些存储数据、停止动画等工作,但是注意不能太耗时,因为这会影响到新Activity的显示,onPause必须先执行完,新的Activity的onCreate->onStart->onResume才会执行
  5. onDestory:表示Activity即将被销毁,在一个生命周期里只会调用一次,主要在这里做一些回收工作和最终的资源释放。

下图详细描述了Activity各种生命周期的切换过程:
Activity的生命周期

具体实例

下面通过一个实例来具体说明一下Activity生命周期的切换过程:
本实例创建了两个Activity:FirstActivity 和 SecondActivity, 在FirstActivity当中加入一个button,通过点击button可跳转到SecondActivity。
1. 启动FirstActivity:系统会调用onCreate()->onStart()->onResume(),FirstActivity进入运行状态。
Activity的生命周期
2. 锁屏或者点击HOME键,系统会调用onPause()->onStop(),FirstActivity被覆盖,进入后台。
Activity的生命周期
3. 解锁或者重新打开APP,系统会调用onRestart()->onStart()->onResume(),FirstActivity重新开始启动,进入前台。
Activity的生命周期
4. 点击Button, 系统会调用FirstActivity.onPause()->SecondActivity.onCreate()->SecondActivity.onStart()->SecondActivity.onResume()->FirstActivity.onStop(),FirstActivity进入后台,SecondActivity创建、启动并进入前台,处于运行状态。
Activity的生命周期
5. 点击返回按钮,系统退出SecondActivity,重新回到FirstActivity,具体调用流程如下。
Activity的生命周期

异常情况下Activity的生命周期

以上就是常用的Activity生命周期的调用方法,接下来将说明另几个重要的与Activity生命周期相关的方法,包括onWindowFocusChanged、onSaveInstanceState、onRestoreInstanceState:

onWindowFocusChanged

onWindowFocusChanged: 顾名思义,就是在Activity窗口获得或者失去焦点时调用,比如上述例子启动FirstActivity进入前台后,FirstActivity获得焦点时会调用此方法;点击Button进入SecondActivity时,FirstActivity进入后台失去焦点时调用此方法,SecondActivity获取焦点时会调用此方法等等。此方法可用于在Activity启动过程中,获取特定View的尺寸大小时调用,因为此时View的绘制过程已经完成。

onSaveInstanceState/onRestoreInstanceState

onSaveInstanceState/onRestoreInstanceState: 这两个方法主要用于在Activity被意外终止时,此Activity数据的保存与恢复工作,主要用于保存一些临时性的数据。那接下来我们要搞清楚两个问题:

什么情况下Activity的onSaveInstanceState会被调用呢?

当某个activity变得”容易”被系统销毁时,该activity的onSaveInstanceState()就会被执行,除非该activity是被用户主动销毁的,主要包括以下三种情况:

  1. 当用户按下HOME键、长按HOME键、从当前Activity启动另一个Activity时。
  2. 由于当前设备的Configuration发生改变,系统默认会重新加载资源包括图片资源、布局资源等,从而导致Activity被销毁重建。此情况下系统会在onStop之前调用onSaveInstanceState方法来保存当前Activity的状态,当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象同时传递给onRestoreInstanceState和onCreate方法,从中取出保存的数据并回复,onRestoreInstanceState在onStart之后调用。比如上述例子FirstActivity从竖屏切换为横屏时的调用流程如下。
    Activity的生命周期
    当Activity在异常情况下需要重新创建时,系统会默认为我们保存当前Activity的视图结构,并在Activity重新创建后为我们恢复这些数据,比如文本框中用户输入的数据、ListView滚动的位置等。我们知道,当系统配置发生改变后,Activity会被重新创建,那么有没有办法不重新创建呢?答案是有的,系统配置有很多内容,如果当某项内容发生改变后,我们不想让系统重新创建的话,可以给Activity指定configChanges属性。系统提供的configChanges的项目和含义有:
    Activity的生命周期
    比如上述例子给FirstActivity添加configChanges属性,如下所示:

    <activity
    android :name= ".activity.FirstActivity"
    android :configChanges= "orientation|screenSize" />

    重新运行App,将FirstActivity从竖屏切为横屏时,调用流程如下:
    Activity的生命周期

  3. 资源内存不足导致低优先级的Activity被杀死。Activity从高到低的优先级为前台Activity 、可见但非前台Activity 、后台Activity。 当系统内存不足时,系统就会按照上述优先级去杀死Activity所在的进程,并在后续通过调用onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。

Activity意外终止时,系统的数据、视图结构存储和恢复机制原理?

首先Activity被意外终止时,Activity会调用onSaveInstanceState去保存数据,然后Activity会委托Window去保存数据,接着Window再委托它上面的*容器去保存数据。顶层容器一般来说是DecorView。最后顶层容器再去一一通知它的子元素来保存数据,这样整个数据保存过程就完成了。这是一个典型的委托思想,上层委托下层、父容器委托子元素去处理一件事情,Android系统中很多应用到这种思想,比如View的绘制过程、事件分发等都是采用类似的思想。至于数据恢复过程也是类似的。