《Android开发艺术探索》笔记 — Activity的生命周期和启动模式

其实艺术探索这本书我很早就买了,传说中的中级工程师迈向高级工程师看的进阶书。哈哈哈!买了后怜香惜玉的看了几天。喔,IPC机制,View事件分发机制,消息机制,一个Drawable都能那么多知识点,好吧,我知道是我技术水平还没到达能看懂这本书。
于是,为了强行看懂书中贴出的源码,我去学了设计模式,接着看了《Android开发进阶-从小工到专家》这本书,也自己开发了两个作品,然后再回来看艺术探索,讲真,现在看艺术探索感觉超级好开心。

笔记只记录重难点,对于详细内容请学习《Android开发艺术探索》

  • 第一章:Activity的生命周期和启动模式

Activity的生命周期全面分析

Activity的生命周期分为两部分:
1. 典型情况下的生命周期
2. 异常情况下的生命周期

典型情况下的生命周期

典型情况下的生命周期是指在有用户参与的情况下,Activity所经过的生命周期的改变

问题:假设当前Activity为A,如果这时用户打开一个新ActivityB,那么B的onResume和A的onPause哪个先执行?
答案:
生命周期执行顺序是这样的:

AonPause() —> BonCreate() —> BonStart() —>BonResume() —> AonStop()

因此,可以得出结论:是A的onPause先执行,然后新的ActivityB再启动。

在新Activity启动之前,栈顶的Activity需要先onPause后,新Activity才能启动。
Android官方文档对onPause的解释是,不能再onPause中做重量级的操作,因为必须onPause执行完成以后,新Activity才能Resume,我们知道onPause和onStop都不能执行耗时的操作,尤其onPause,我们应尽量在onStop中做操作,从而使的新的Activity尽快显示出来并切换到前台

异常情况下的生命周期

异常情况下的生命周期是指Activity被系统回收或者当前设备的Configuration发生改变从而导致Activity被销毁重建,例如旋转屏幕

情况1:资源相关的系统配置发生改变导致Activity被杀死并重新创建

比如说当前Activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity会被销毁并且重新创建,当然我们也可以阻止系统重新创建我们的Activity

由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态,这个方法的调用时机是在onStop之前,这个方法只会出现在Activity被异常终止的情况
当Activity被重新创建后,系统会调用onRestoreInstanceState,并把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法

具体针对某一个View,系统能为我们恢复哪些数据,可以查看View的源码。和Activity一样,每一个View都有onSaveInstanceState和onRestoreInstanceState。比如TextView保存了自己的文本选中状态和文本内容。

关于保存和恢复View层次结构,系统的工作流程是这样的,首先Activity被意外终止,Activity会调用onSaveInstanceState去保存数据,然后Activity会委托Window去保存数据,接着Window再委托他上面的顶级容器去保存数据,顶级容器是一个ViewGroup,最后顶层容易在去一一通知他的子元素来保存数据
这样整个数据保存过程就完成了。这是一种典型的委托思想,上层委托下层,父容器委托子元素去处理一件事情,至于恢复数据过程也是类似的

针对onSaveInstanceState方法,系统只会在Activity即将被销毁,并且有机会重新显示的情况下才会去调用它,当Activity正常销毁时候,系统不会调用onSaveInstanceState,因为被销毁的Activity不可能再次被显示。
旋转屏幕,属于Activity被销毁,并且有机会重新显示的情况,肯定是要重新显示的啊。但是如果我按back键退出,正常销毁Activity,系统怎么知道我要再次回来?那么此时Activity显然不会调用onSaveInstanceState去保存数据

情况2:资源内存不足导致低优先级的Activity被杀死

Activity优先级从高到低可分为
1. 前台Activity,正在和用户交互,优先级最高
2. 可见但非前台Activity,比如Activity中弹出一个(加载)对话框,导致Activity可见但是位于后台无法和用户直接交互
3. 后台Activity,比如启动新的Activity后,已经被暂停的Activity,优先级最低

当系统内存不足,系统会杀死优先级较低的Activity所在进程,并在后续通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据

一些后台工作不适合脱离四大组件而独自运行在后台中,这样进程很容易被杀死,比较好的方法是将后台工作放在Service中从而保证进程有一定的优先级,这样就不会轻易被系统杀死

当我们不想系统重新创建Activity,可以给Activity指定configChanges属性,
比如不想让Activity在屏幕旋转时重新创建,就可以如下配置

android:configChanges = "orientation"

Activity的启动模式

standard标准模式:每次启动一个Activity都会重新创建一个新的实例不管这个实例是否已经存在
在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中,比如ActivityA启动了AcitivityB(B是标准模式),那么B就会进入到A所在的栈中

当我们用ApplicationContext去启动standard模式的Activity的时候会报错。
因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但是由于非Activity类型的Context(如ApplicationContext)并没有所谓的任务栈,所有这就有问题了,解决这个问题的方法是为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位,启动的时候为他创建一个新的任务栈,这个时候启动Activity实际上是以singleTask模式启动的

singleTop栈顶复用模式:如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建。同事他的onNewIntent方法会被回调,如果新的Activity实例已经存在但不是位于栈顶,那么新的Activity仍然会重新创建

singleTask栈内复用模式:只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调其onNewIntent方法,
同时由于singleTask默认具有clearTop的效果,会导致栈内所有在这个singleTask模式Activity上面的Activity全部出栈
假设前台任务栈是AB,而后台任务栈是两个singleTask模式的CD,D在栈顶,如果此时请求C,那么后台任务栈都会被切换到前台,而且D出栈,因为D在C的上面,详见P19页

singleInstance单实例模式:单例模式的Activity只能单独位于一个任务栈,系统会为单例模式的Activity创建一个新的任务栈,然后独自在这个新的任务栈中,由于栈内复用,后续的请求均不会创建新的Activity

IntentFilter的匹配规则

IntentFilter的过滤信息由action,category,data

action的匹配规则:要求Intent中的action存在且必须和过滤规则中的其中一个action相同。区分大小写

category的匹配规则:Intent可以没有category,但是如果一旦有category,不管有几个,每个都要能够和过滤规则中的任何一个category相同,为什么不设置category也能匹配,原因是系统在调用startActivity或者startActivityForResult的时候会默认为Intent加上"android.intent.category.DEFAULT"这个category

data的匹配规则:data由两部分组成,mimeType和URI,mineType是指媒体类型,比如image/jpeg。
data匹配要求intent中必须含有data数据,并且data数据,能够完全匹配过滤规则中的某一个data,这里的完全匹配是指过滤规则中出现的data部分也出现在了intent中的data中
如果没有指定URI,URI默认值为content和file

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值