Activity的生命周期和启动模式

Activity的生命周期和启动模式

1.1 Activity的生命周期分析

Activity的生命周期分为两个部分,一个是典型情况下的生命周期,另一个是异常情况下的生命周期。所谓的典型情况下的生命周期是指,是指有用户参与的情况下,Activity所经过的生命周期的改变。而异常情况下的生命周期是指Activity被系统回收,或者当前设备的Configuration发生改变从而导致Activity被销毁重建。

1.1.1 典型情况下的生命周期

在正常情况下,Activity会经历的生命周期有:

  • onCreate:表示Activity正在被创建,我们可以在这个方法中做一些初始化的工作。
  • onStart:表示Activity正在被启动,这个时候Activity已经可见了,但是还没有出现在前台,还无法和用户交互。(可以理解为Activity已经显示出来了,但是我们还看不见)
  • onRestart:表示Activity重新启动,此时Activity从不可见状态变为可见状态时,onRestart就会被调用。
  • onResume:表示Activity已经可见了,并且出现在前台。当Activity界面获取焦点的时候(界面按钮可以被点击,文本框可以输入内容)。
  • onPause:表示Activity已经停止,此时Activity界面失去焦点的时候(界面按钮不可以被点击,文本框不可以输入内容,但是界面,用户仍然能看见)。此方法通常用于确认对持久性数据的未保存更改、停止动画以及其他可能消耗 CPU 的内容,不能做很耗时的操作
  • onStop:表示Activity即将停止,此时Activity界面用户不可见时。可以做稍微重量级的回收工作,但是也不能太耗时。
  • onDestroy:表示Activity即将被销毁,可以做一些回收工作和最终的资源释放。

可将Android典型情况下的生命周期分为三种

  • 完整的生命周期

    onCreate-->onStart-->onResume-->onPause-->onStop-->onDestroy
  • 可视生命周期

    onStart-->onResume-->onPause-->onStop
  • 前台生命周期

    onResume-->onPause

下面是google官方给出的Activity生命周期的切换过程:

activity_lifecycle.png

需要注意的问题

因为前一个Activity执行完成onPause方法以后新Activity的onResume才能执行。所以我们如果在onPause或者onStop中执行耗时操作,尽量在onStop中执行。

1.1.2 异常情况下的生命周期分析

当系统配置发生变化时,或者系统内存不足时,Activity可能被杀死。

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

    当系统配置发生改变后,Activity会被销毁onPause、onStop、onDestroy都会被调用。
  • 除此以外系统还会调用onSaveInstanceState来保存当前的Activity的状态。这个方法的调用时机是在onStop之前,和onPause没有什么时序关系。该方法正常情况下不会被调用,只有Activity以外终止的时候才会被调用。
  • Activity重新被创建的时候,系统会调用onRestoreInstanceState,我们可以通过该方法取出,onSaveInstanceState方法中所保存的数据。该方法的调用时机发生在onStart之后。
  • 资源内存不足导致低优先级的Activity被杀死

    Activity按照优先级从高到低的可以分为三种:
  • 前台Activity——————正在和用户交互的Activity,优先级最高。
  • 可见但非前台Activity——————比如Activity弹出个对话框。
  • 后台Activity——————已经被暂停的Activity,比如执行了onStop,优先级最低

Tips:
当系统配置改变后,Activity会被重新创建,如果想Activity不被系统重新创建那么我们可以设置Activity的configChanges属性。

android:configChanges="orientation|screenSize"

Activity的启动模式

activity的启动模式共有四种。

  • standard:标准模式,也是系统的默认模式。每次启动一个Activity都会重新创建一个新的实例。这种模式下,谁启动了这个Activity,那么这个Activity就在启动它那个Activity的堆栈中。

Tips:
ApplicationContext启动standard模式的Activity的时候会报错。因为非Activity的Context并没有任务栈。要解决这个问题的方法,为带启动Activity指定FLAG_ACTIVITY_NEW_TASK标记为。

  • singleTop:栈顶复用模式。如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时他的onNewIntent方法会被回调。如果不是位于栈顶,那么新的Activity仍然会被重新创建。
  • singleTask:栈内复用模式。这是一种单实例模式,这种模式下只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,系统也会回调onNewIntent。
    注意:
  • 任务栈S2和ActivityD两个都不存在,那么系统先创建任务栈S2,然后将D的实例压入到栈S2中。
  • 如果存在S2直接将D的实例压入到栈S2中。
  • singleTask启动模式自带cleartop的功能,例如ABCD,四个Activity,从栈顶到栈底。如果这时候启动DActivity那么任务栈中只剩下D的实例。
  • singleInstance:单实例模式,加强的singleTask模式,除了具有singleTask的所有特性以外,这种模式的Activity只能单独位于一个任务栈中。

Activity的Flags

主要介绍一下比较常用的Flags

  • FLAG_ACTIVITY_NEW_TASK:这个标记位的作用是为Activity指定“singleTask”启动模式。
  • FLAG_ACTIVITY_SINGLE_TOP:这个标志位的作用是为Activity指定"singleTop"启动模式。
  • FLAG_ACTIVITY_CLEAR_TOP:当这个activity启动的时候,在同一个任务栈中位于它上面的Activity都要出栈。
  • FLAG_ACTIVITY_EXCLUDE_RECENTS:具有这个标记的Activity不会出现在历史的Activity的列表中,当某些情况下我们不希望用户通过历史列表返回到我们的Activity可以使用这个。等同于在XML中指定Activity的属性android:excludeFromRecents="true"

IntentFilter的匹配规则

我们知道启动Activity分为两种,显示调用和隐式调用。显示调用需要指定被启动对象的组件信息,包括包名类名,而隐式调用需要明确指定组件信息。隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息。下面我们来介绍一下IntentFilter中的各种属性和匹配规则。

  • action的匹配规则:action是一个字符串,action的匹配要求Intent中的action存在并且必须和过滤规则中的其中一个action相同,action区分大小写。
  • category的匹配规则:category是一个字符串,Intent中的每一个category都必须和过滤规则中的category相同。Intent中可以没有category,仍然可以匹配成功。因为系统在调用startActivity或者startActivityForResult的时候会为Intent加上“android.intentcategory.DEFAULT”这个category。
  • data的匹配规则:data的语法
    <pre><code>
    < data android:scheme="string"
    android:host="string"
    android:port="string"
    android:path="string"
    android:pathPattern="string"
    android:pathPrefix="string"
    android:mimeType="string"/>

</pre></code>
data由两部分组成,mimeType和URI。mimeType指媒体类型,比如image/jpeg、audio/mpeg4generic和video/*等,可以表示图片、文本、视频等不同的媒体格式,而URI中包含的数据就比较多了。下面是URI的结构:

<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]

content://com.example.project:200/folder/subfolder/etc

http://www.baidu.com:80/search/info

下面介绍每个数据的含义。

  • Scheme:URI的模式,比如http、file、content等。如果URI中没有指定scheme,那么整个URI的其他参数是无效的。
  • Host:URI的主机名,比如www.baidu.com,如果host未指定,那么整个URI的其他参数是无效的。
  • Port:URI中的端口号,比如80,当URI中的scheme和host参数指定的时候,port参数才有意义。
  • Path、pathPattern和pathPrefix:这三个参数表示路径信息。
  • path:表示完整路径信息
  • pathPattern:表示完整路径信息,但是它里面可以包含通配符“ * ”,“ * ”表示0个或者多个字符。
  • pathPrefix:表示路径前缀信息。

注意:
如果要为Intent指定完整的data,必须调用setDataAndType方法,不能先调用setData在调用setType,因为两个方法彼此会清除对方的值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容