Android Activity的生命周期与异常生命周期的分析

此文是看完 Android开发艺术探索 和一些大神的博客的理解与总结。

Activity的生命周期分为两个部分内容,一个是正常情况下的生命周期,另一部分是异常情况下的生命周期。这里对两个部分分别介绍。

下面是官方文档的生命周期流程图
这里写图片描述

一.正常情况下的生命周期
1.onCreate:表示Activity正在被创建。这是生命周期的第一个方法,该方法中我们经常处理一些初始化工作。

2.onStart:表示Activity正在被启动,且Activity已经可见,但没有获取到焦点(焦点是指我们可以跟该界面进行交互),即还没有出现在前台。

3.onRestart:表示Activity正在被重启。一般情况下,Activity从不可见到可见会调用此方法。这种情况一般是用户行为导致,比如用户按Home键切换到桌面或者打开了一个新的Activity,这个时候当前的Activity就会暂停,调用onPause和onStop方法,接着用户又回到这个Activity就会调用onRestart方法,接着会调用onStart和onResume。

4.onResume:表示Activity可见,并且出现在前台,已经获取焦点,可以和用户进行交互了。

5.onPause:表示Activity正在停止,当前Activity可见但失去焦点。正常情况下,onStop会紧接着被调用。在特殊情况下,这个时候快速再回到当前Activity,那么onResume会被调用(一般用户操作很难出现这种情况)。该方法中一般处理一些数据存储、动画停止等操作,但注意不能太耗时,因为新的Activity的onResume的调用会在原Activity的onPause执行完之后调用。

6.onStop:表示Activity即将停止,已经完全不可见,Activity为不可见时才会调用此方法。例如,将当前Activity设置为透明主题,这个时候打开一个新的Activity,会调用当前Activity的onPause,然后调用新Activity的onCreate、onStart、onResume,这个时候由于原Activity是透明的,还可以看到,即还在前台,所以并不会调用onStop方法;若不是透明,即不可见,则会调用onStop方法。

7.onDestroy:表示Activity即将被销毁,这是生命周期最后一个回调。可以做一些回收工作和资源释放。

注: 可见指示用户已经可以看到,通常指此时还未获取到焦点,即还处于后台。处于前台是指用户可以看到,已经获取到焦点,即可以和界面进行交互。
例如当一个Activity上弹出一个对话框,此时该Activity是可见的,但无法与用户交互,失去焦点,处于后台。该对话框是处于前台的,可以和用户进行交互,具有焦点。

总结:
1.onStart和onStop、onPause和onStop从描述上来看,我们会觉得这样会有些多余,甚至只保留一对也可以。但是Android系统为什么会用这样两个方法呢?我们这里通过可见和处于前台(即获取焦点)来分析,onStart和onStop是从是否可见这个角度来回调的,而onResume和onPause是从是否在前台这个角度来回调的。所以我们可以清楚的知道,当一个Activity可见、处于前台、不可见、处于后台会调用这4个方法。

2.第二个点是假设当前Activity为A,这时用户打开一个新的Activity B,那么B的onResume和A的onPause哪个先执行呢?我们可以想到,当一个新界面要启动的时候,是要处在前台的(获取到焦点),所以只有原Activity失去焦点,新的Activity才会获得焦点,所以A的onPause执行后才会执行B的Activity的生命周期方法,执行完B的onResume后,A已经完全不可见,所以会回调A的onStop方法。

3.Android官方文档对onPause的解释有这么一句话:不能再onPause中做重量级的操作,因为必须onPause执行完成以后新Activity才能Resume。所以我们尽量在onStop中操作,从而使得新Activity尽快显示出来并切换到前台,当然,onStop中也不能执行耗时的操作。

二.异常情况下的Activity生命周期
常见的异常情况有两种:当资源相关的系统配置发生改变以及系统内存不足时,Activity就可能被杀死。下面我们具体分析这两种方法:

  1. 情况1: 资源相关的系统配置发生改变导致Activity被杀死并重新创建
    比如当前Activity处于竖屏状态,如果旋转屏幕,由于系统配置发生改变,在默认的情况下,Activity就会被销毁并且重新创建,当然我们可以通过配置来阻止系统重新创建Activity。

    当系统配置发生变化后,Activity会被销毁,其onPause、onStop、onDestroy方法会被调用,由于是异常情况下终止程序,所以会调用onSaveInstanceState方法来保存当前Activity的状态,该方法会在onStop之前调用,但和onPause无既定顺序。当Activity被重新创建后会调用onRestoreInstanceState方法,并把Activity销毁时onSavaInstanceState方法所保存数据的Bundle对象同时传递给onRestoreInstanceState和onCreate方法,onRestoreInstanceState方法在时序上是在onStart之后。
    并且,在onSavaInstanceState和onRestoreInstanceState方法中系统为我们做了一定的恢复工作。当Activity在异常情况下被销毁并且被重建时,系统会默认为我们保存当前的Activity视图结构,并且重启后为我们恢复这些数据,比如文本框内的数据,listview的滚动位置等,这些View相关的状态系统都能够默认为我们恢复。
    保存和恢复View层次结构的工作流程: 首先Activity被意外终止,Activity会调用onSaveInstanceState去保存数据,然后Activity会委托Window去保存数据,接着Window会再委托它上面的顶级容器去保存数据。顶层容器是一个ViewGroup,一般来说很可能是DecorView。最后顶层容器再一一通知它的子元素去保存数据。这是一种典型的委托思想。数据恢复过程也是类似的。
    onCreate和onRestoreInstanceState可以获取之前保存的数据,他们的区别是onRestoreInstanceState一旦被调用,Bundle对象一定是有值的,onCreate方法如果是正常启动Bundle对象为null,所以我们通过onCreate取出异常销毁后启动的恢复数据时,必须要对Bundle对象进行判断。
    对于onSaveInstanceState我们还要说明一点,就是系统只会在Activity即将被销毁并且有机会重新显示的情况下才会调用这个方法。正常情况下的Activity退出是不会调用onSaveInstanceState的,因为Activity不可能被再次显示,对比一下屏幕旋转,Activity被销毁后会立即创建一个新的Activity实例,这个时候Activity有机会再次立刻展示,所以系统需要存储数据。

  2. 情况2: 资源内存不足导致低优先级的Activity被杀死
    这种情况不好模拟,但是其数据存储和恢复的过程和情况1是完全一样的。

现在我们知道当发生系统配置变化后,Activity会重建,那么有什么办法可以不重建吗?我们可以对其进行相应的配置来处理这个问题。可以给Activity的configChanges指定属性。多个属性用”|”连接。
常用的属性有
locale:设备的本地位置发生了变化,一般指切换了系统语言
orientation:屏幕方向发生了变化,比如旋转了手机屏幕
keyboardHidden:键盘的可访性发发生了变化,比如用户调出了键盘

screenSize:当屏幕的尺寸信息发生变化时,比如屏幕旋转,尺寸会变化
smallestScreenSize:设备的物理屏幕尺寸发生改变,这个项目和屏幕的方向没有关系,仅仅表示在实际的物理屏幕的尺寸发生改变的时候发生,比如用户切换到了外部的显示设备。

另外需要注意的一点是: screenSize和smallestScreenSize,它们两个比较特殊,它们的行为和编译选项有关,但和运行环境无关。当编译选项中的minSdkVersion和targetSdkVersion均低于13时,它们两个不会导致Activity重启,否则会重启。
android:configChanges=”orientation | screenSize”

这篇文章就写到这里,有什么问题希望大家能指出。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值