Activity的生命周期和启动模式

一、Activity生命周期全面解析

1、典型情况下的生命周期分析

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

  • (1)onCreate():表示Activity正在创建,这是生命周期的第一个方法,进行一些初始化操作,比如说加载界面布局资源、初始化Activity所需数据。
  • (2)onRestart():表示Activity正在重新启动。一般情况下,当前Activity从不可见变为可见状态时,此方法会被调用。这种情况一般是用户行为所导致。
  • (3)onStart():Activity正在被启动,此时可见(Activity已经显示出来了但是还是看不见)但是不能和用户交互。
  • (4)onResume():Activity可见且处于前台可以进行交互
  • (5)onPause():表示Activity正在停止,正常情况下onStop()方法会调用。特殊情况下,如果快速回到当前Activity,onResume()会被调用。此时可以做一些存储数据、停止动画等操作,但是不能太耗时。
  • (6)onStop():Activity即将停止,可以做一些稍微重量级的回收操作,同样不能太耗时。
  • (7)onDestroy():Activity即将被销毁,Activity最后的一个生命周期,可以做一些回收和最终资源释放。


    Activity声明周期和切换过程
特殊情况:

(1)针对一个特定的Activity,第一次启动会调用:onCrate() -> onStart() -> onResume()
(2)当用户打开新的Activity或者切换到桌面时,回调如下:onPause() -> onStop(),特殊情况,如果新打开的Activity是一个透明主题或者是对话框,则并不会调用onStop()
(3)当用户再次回到原Activity时,回调如下:onRestart() -> onStart() -> oonResume()
(4)当用户按back键回退时,回调如下:onPause() -> onStop() -> onDestory()
(5)当Activity被回收后再次打开,生命周期回调和(1)相同
从一个Activity跳转到另一个Activity生命周期:当前Activity生命周期会先onPause先执行,另一个的onResume后执行。

Activity启动流程简单理解

启动Activity的请求会由Instrumentation处理,然后通过Binder向AMS发请求,AMS内部维护了一个Activity栈并负责栈内Activity的状态同步,AMS通过ActivityThread去同步Activity状态,从而完成生命周期方法调用。

异常情况下的声明周期分析

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

默认情况下,如果Activity不做特殊处理,那么当系统配置发生改变之后Activity就会被销毁,并重新创建。


异常情况下,Activity重建过程

当系统配置发生改变后,Activity会被销毁,其onPause,onStop,onDestroy均会被调用,同时由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState方法来保存当前Activity状态,状态数据保存到Bundle对象中。这个方法调用时机是在onStop方法之前,和onPause方法没有既定的时序关系。onSaveInstanceState方法只有在Activity被异常终止的情况下调用。Activity被重建过后,系统会调用onRestoreInstanceState(),并且把onSaveInstanceState方法保存的Bundle对象作为参数传递给此方法和onCreate()方法,然后在判断Activity是否被重建了,如果重建了就取出数据并恢复。从时序上看onRestoreInstanceState方法会在onStart方法之后。

在onSaveInstanceState和onRestoreInstanceState方法中,系统自动做了一定的恢复工作。当Activity在异常情况下重新创建时,系统会默认保存当前Activity视图结构,并且在Activity重建过后恢复这些数据

保存和恢复View层次结构,系统工作流程:

  • 保存过程:Activity被意外终止时,Activity会调用onSaveInstanceState保存数据,然后Activity会委托window去保存数据,接着window再委托它上面的顶层容器去保存数据。顶层容器是一个ViewGroup,一般来说是一个DecorView,最后顶层容器会通知它的子元素来保存数据
  • 恢复过程:恢复数据时,可以在onRestorInstanceState或者在onCreate方法中(二者区别是onRestoreInstance方法一旦被调用,其参数Bundle,一定是有值的,不需要额外的判空;但是onCreate不行,需要进行判空),这两个方法任选一个进行数据恢复,但官方建议onRestoreInstanceState方法。

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

数据存储和恢复和情况1一致。
Activity优先级,Activity按照优先级从高到低,可分为如下三种情况:
(1)前台Activity——正在和用户交互的Activity,优先级最高
(2)可见但非前台——Activity可见,但是位于后台不能交互
(3)后台Activity——已经暂停了Activity,比如执行了onStop,优先级最低

当系统内存不足时,系统就会按照上述优先级去杀死目标Activity所在进程,并通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。如果一个进程中没有四大组件在执行,那么这个进程就会很快被杀死。

如果配置了android:configChanges = "Orientation|ScreenSize"属性,那么就不需要系统重新创建Activity,而是配置过后,系统调用onConfigChange()方法,进行一个特殊的处理


configChanges的属性值

Activity启动模式

Activity栈(任务栈):一种先进后出的栈结构,进行交互的Activity位于任务栈栈顶,每按一下back键,就会有一个Activity出栈,直到栈为空时,系统就会回收这个栈

standard(标准模式)

系统默认模式。每启动一个Activity都会重新创建一个新的实例,不管这个实例是否存在。被创建的Activity生命周期符合正常情况下的生命周期。一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈。谁启动这个Activity就会运行在启动它的Activity的任务栈中

singleTop(栈顶复用)

如果新启动的Activity的实例为任务栈的栈顶,那么就不会重新创建,同时他的onNewIntent方法会被回调,通过此方法的参数我们可以取出当前请求的信息。需要注意的是,这个Activity的onCreate、onStart不会被系统调用,因为它并没有发生改变。如果新启动的Activity的实例不位于栈顶就会重新创建。

singleTask(栈内复用)

栈内复用是一种单例模式,只要新启动的Activity在任务栈中存在实例就不会创建直接使用,如果不是位于栈顶就会把这个实例上面的所有Activity实例全部出栈(默认的clearTop效果),同时回调onNewIntent方法
TaskAffinity参数:可翻译为任务相关性,标识了一个Activity所需要的任务栈名字,默认情况下都是应用的包名。这个属性主要和singleTask启动模式和allowTaskReparenting配对使用,在其他情况下没有任何意义。

singleInstance(单实例模式)

加强的singleTask,此种模式的Activity实例只能单独位于一个Activity栈中。

Activity的Flags,Activity常用标记位

  • FLAG_ACTIVITY_NEW_TASK:对应singleTask模式
  • FLAG_ACTIVITY_SINGLE_TOP:对应singleTop模式
  • FLAG_ACTIVITY_CLEAR_TOP:具有此标记位的Activity,当它启动时,在同一任务栈中所有位于它上面的Activity都要出栈。一般和singleTask配合使用
  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有此标记的Activity不会出现在历史的Activity列表中,等同于XML中指定Activity的属性:android:excludeFromRecents= "true"

IntentFilter的匹配规则

IntentFilter的过滤信息有:action、category、data
为了匹配过滤列表,需要同时匹配过滤列表中的过滤信息,否则匹配失败。一个过滤列表的action、category、data可以有多个,所有的action、category、data构成不同类别,同一类别的信息共同约束当前类别的匹配过程。一个Activity的IntentFilter可以有过个,一个Intent只要匹配任何一组IntentFilter就能够启动Activity

1、action的匹配规则

action是一个字符串,系统预定义了一些action,同时我们也可以自定义action。action的匹配规则是Intent的action必须能够和IntentFilter中的action匹配(字符串值完全一样,需要区分大小写)。一个IntentFilter可以有多个action,只要匹配一个action都能匹配成功。如果intent中没有指定action,那么匹配失败

2、category匹配规则

category是一个字符串,系统预定义了一些category,我们也可以自定义。category匹配规则:要求Intent中如果含有category,那么所有的category都必须和IntentFilter中其中一个category相同。也就是,Intent中出现了category,不管有几个,对于每个category来说,它必须是IntentFilter中已经定义的category

3、data匹配规则

data匹配规则和action相似,如果IntentFilter中定义了data,那么Intent中必须定义可匹配的data,data使用mimeType指定媒体类型。


data语法

data由两部分组成:mimeType和URI。mimeType指定媒体类型,URI包含以下结构:


URI结构
  • scheme:URI模式,如果没有指定scheme,那么整个URI都无效
  • host:URI主机名,如果没有指定host,那么整个URI都无效
  • post:URI端口号,仅当URI制定了scheme和host参数时才有效
  • path、pathPattern和pathPrefix:这三个参数表示路径信息,path表示完整路径信息;pathParttern也表示完成的路径信息,但是它可以包含通配符“ * ”(表示0个或多个任意字符,需要注意的是,如果想表示真是的字符串则需要改成“\*,“\”则要写成“\\”);pathPrefix表示路径的前缀信息。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容