Activity异常被关闭的两种情况

Activity异常关闭的两种情况

情况1:资源相关的系统配置发生改变导致Activity被杀死并重新创建,当程序启动时系统就会根据当前设备的情况去加载合适的Resource资源,比如说横屏手机和竖屏手机会拿到两张不同的图片(设定了landscape或者portrait状态下的图片).比如说当前activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了变化,在默认情况下,Activity就会被销毁并且重新创建,当然我们也可以组织系统重新创建我们的Activity.

在默认情况下,如果我们的Activity不做特殊处理,那么当系统配置发生改变后,Activity就会被销毁并重新创建
在这里插入图片描述
当系统配置发生改变后,Activity会被销毁,其onPause,onStop,onDestroy均会被调用,同时由于Activity实在异常情况下终止的,系统会调用onSaveInstanceState()来保存当前activity的状态.这个方法的调用时机是在onStop之前,它和onPause没有既定的时序关系,既有可能实在onPause之前调用,也可能是在onPause之后调用,需要强调的一点就是,这个方法只会出现在activity被异常终止的情况下,正常情况下系统不会回调这个方法,当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数传递给onRestoreInstanceState和onCreate方法来判断activity是否被重建了,如果被重建了,那么我们就可以取出之前保存的数据并恢复,从时序上来说,onRestoreInstanceState的调用时机在onStart之后.

同时,我们知道,在onSaveInstanceSta和onRestoreInstanceState方法中,系统自动为我们做了一定的恢复工作,当Activity在异常情况下需要重新创建时,系统会默认为我们保存当前activity的视图结构,并且在activity重启后为我们恢复这些数据,比如文本框中用户输入的数据,ListView滚动的位置等.这些View相关的状态系统都能够默认为我们恢复.具体针对某一个特性的View系统能为我们恢复那些数据,我们可以查看View的源码,和activity一样,每个View都有onSaveInstanceState和onRestoreInstanceState这两个方法.

接受的位置可以选择onRestoreInstanceState或者onCreate,二者的区别是:onRestoreInstanceState一旦被调用,其参数bund saveInstanceState一定是有值的,我们不用额外的判断是否为空,但是onCreate不行,onCreate如果是正常启动的话,其参数Bundle SaveInstanceState为null,所以必须额外判断,这两个方法任意一个都可以进行数据恢复,官方文档建议采用onRestoreInstanceState去恢复数据.


情况2:资源内存不足导致低优先级的activity被杀死
首先,关注下优先级的问题:

  • 1.前台activity,正在和用户交互的activity,优先级最高
  • 2.可见但非前台activity,比如activity中弹了个对话框,导致activity可见但是位于后台无法和用户直接交互
  • 3.后台activity,已近被暂停的activity,比如执行了onStop,优先级最低.

当系统内存不如时,系统就会按照上述优先级去杀死目标activity所在的进程,并在后续通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据,如果一个进程中没有四大组件在执行,那么这个进程将很快被系统杀死,因此一些后台工作不适合脱离四大组件而肚子运行在后台中,这样进程很容易被杀死,比较好的方法就是将后台工作放入Service中,从而保证线程有一定的优先级,这样就不会轻易的被系统杀死.

如何使得activity不被重新创建?

当系统配置发生变化后,Activity会被重新创建,那么有没有办法不重新创建呢?答案是有的.
系统配置中有很多内容,如果当某项内容发生改变后,我们不想系统重新创建Activity可以给configChanges属性.

比如不想让Activity在屏幕旋转的时候重新创建,就可以给configChanges属性添加orientation这个值:

android:configChanges = "orientation"

如果我们想指定多个值,可以用"|"连接起来,比如

android:configChanges= "orientation|keyboardHidden".

系统配置中所含的项目是非常多的,如下表:

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

从上表可以知道,如果我们没有在Activity的configChanges属性中指定该选项的话,当配置发生改变后就会导致Activity重新创建.常用的项目只有locale.orientation和keyboardHidden这三个选项.其他的很少用.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值