Hello,大家好!今天周一,大家鼓足干劲就是干,反手就是一巴掌(哈哈)。
Photo by lwowomeme from polaxiong
这篇文章是关于 Activity 的一些总结(小白文,莫喷),其中部分是刚哥《艺术探索》的读书笔记,Activity 作为四大金刚中出现频率最高的组件,我们可以在各个地方都可以见到它。总结过程中也借此好好回顾下,分享给大家,当然也希望各位大牛能不吝赐教。
Activity 的四种状态
关于什么是 Activity 的概念我就不介绍了,都烂大街了。Activity 有多种状态,它可以在这几种状态之间切换,并以此影响着 Activity 的生命周期。
Running:
表明 Activity 处于活动状态,用户可以点击屏幕并作出响应,这时候处于 Activity 栈顶。
Paused:
表明 Activity 失去焦点或被非全屏 Activity 覆盖,失去和用户交互的能力,在内存不紧张情况下,所有状态信息都还会存在。
stopped:
被其他 Activity 完全覆盖,不再是可见的,状态信息同上。
Killed:
Activity 已经被系统回收且所有状态信息不存在。
从上面我们可以看出,用户者不同的操作行为会让 Activity 在不同的状态间切换,接下来我们来看看它的生命周期。
Activity 的生命周期
先来张经典的官方 Activity 生命周期图:
Activity 生命周期
我们来回顾下上面的方法,看看自己还记得多少(偷笑):
onCreate()
这是生命周期的第一个方法,此时 Activity 正在创建,一般我们会做一些初始化工作,如加载界面、初始化数据等。
onStart()
此时 Activity 正在启动,这时的 Activity 已经可见,可是还没有出现在前台,也就无法和用户进行交互。
onResume()
这时候的 Activity 已经可见了且是出现在前台了,
onPause()
此时的 Activity 正在停止,然后 onStop()就会被调用,一般我们可以做些存储数据等操作,
onStop()
此时的 Activity 即将停止。
onRestart()
此时 Activity 正在重新启动,假如 Activity 从不可见重新变为可见的时候,这个方法就会被调用,如打开一个新的页面然后又返回当前 Activity。
onDestroy()
这是生命周期最后一个回调方法,此时的 Activity 即将销毁,通常我们会做写资源释放等操作。
生命周期的分析
Activity 启动:onCreate() -> onStart() -> onResume()
Home 键返回主界面或被覆盖(Activity 不可见):onPause() -> onStop()
回到原 Activity:onRestart() -> onStart() -> onResume()
退出当前 Activity:onPause() -> onStop() -> onDestroy()
以上就是 Activity 的生命周期分析,各位是不是对整个流程信手捏来,我只能说 666 了!
最后这里再说一个问题,如果当前 Activity 为 A,此时用户再打开一个新的 Activity 页面 B,
你以为生命周期介绍到这里就没了?当然不是,上面那是正常情况下,难不保有意外,不然保险公司为啥赚的盆满坡满?
这些意外就是系统配置发生了改变,如旋转屏幕。又或是因为内存不足导致 Activity 被 Kill 掉,都是极有可能的。
系统配置发生改变,Activity 就会被销毁然后再重新创建,如果我们不想让 Activity 重新创建,我们也可以通过 Activity 指定 configChanges 属性值为 orientation 值。同时因为 Activity 在这种意外情况下被销毁,系统就会通过 onSaveInstanceState()方法 保存当前 Activity 的状态信息,然后我们可以通过 onRestoreInstanceState()方法 取出并恢复保存的数据,关于这方面的 View 的存储和恢复,具体我就不介绍了,大家感兴趣的可以自己去看看,当然大家可能早就熟门熟路了,嘿嘿。当然了,Android 系统默认实现了控件的状态缓存,减少了开发者的工作量。
内存不足导致 Activity 被杀死,当然系统也是按照情况来杀掉进程的,这也就是进程优先级,它们之间的关系如下:
优先级越大越不容易被杀死,从这里也可以看出,一些重要的后台工作应当放入 Service 中保证不被系统杀死。
Activity 的 LaunchMode
在介绍启动模式前,我们先来说说 Android 的任务栈,Android 系统通过栈保存 App 的 Activity,这个栈也就是 Task,表示若干个 Activity 集合,一个 Task 中的 Activity 可以来自不同的 App。对于栈,大家应该都很熟悉,它是一个先进后出的线性表,我就不啰嗦了。
启动模式一共有四种启动模式:standard,singleTop,singleTask和singleInstance。
对于它们之间的区别以及功能我就不介绍了,想必大家应该耳熟能详了。那么如何设置启动模式?
通过 AndroidMenifest 指定:
通过 Intent 设置 Flag 指定启动模式:
还有其他一些常用的 Flag 大家也可以去搜一搜,我这里也不一一介绍了。
IntentFilter 使用
我们都清楚启动 Activity 可以分为显式调用和隐式调用。显式调用,顾名思义就是明确指定被启动目标对象的信息,非常简单也就不详细介绍了。而隐式调用则相反,它需要 Intent 去匹配目标对象的 IntentFilter 设置的过滤信息,IntentFilter 的过滤信息有 action、category、data。假如与目标对象的不一致则无法启动目标对象。
一个过滤信息表中的 action、category 和 data 可以有多个,一个 Activity 当中也可以有过个过滤信息表 intent-filter,只要一个 Intent 能对应其中一组过滤信息表就可以启动对应的目标对象。
action
action其实是字符串,系统也定义了一些 action,还记得那会入门的拨打电话小案例吗?嘿嘿,当然我们可以自定义action。只要 Intent 中的 action 能够和过滤列表中的任何一个 action 值相同就配对成功,值相同指的是 action 的字符串值是一样的。
category
category 也是字符串,但是它的配对规则和 action 不同,它要求如果 Intent 中如果含有 category 信息,那么这些所有的 category 都要和过滤列表中的任意一个 category 值相同,也就是 Intent 中的 category 已经是在过滤表中定义过的 category。
data
data 由 mimeType 和 URL 组成,mimeType 是媒体类型,这里就一笔带过吧!其实 data 的配对规则和 action 是相似的,它要求 Intent 中含有 data 数据且可以和过滤列表中任意一个 data 匹配,这个过程是过滤列表中的 data 也出现在 Intent 的 data 中,即配对成功。
好了,到这里这篇文章也到了尾声,不知道各位看完是否有收获吗?大家可别因为是继承而忽视,当然这篇文章说是总结,却不够详细,如关于 View 的存储和恢复及源码等也还没深入,以及各种启动模式的应用场景等等,因为时间关系没有总结成文,很多时候自己会但是要提笔写出来真的挺费时间的,怎么说呢,抛砖引玉吧!接下来和大家一起共同进步!
领取专属 10元无门槛券
私享最新 技术干货