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

1.1 Activity的生命周期全面分析

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

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

一般情况下Activity生命周期执行的顺序是:onCreate()->onRestart()->onStart()->onResume()->onPause()->onStop()->onDestory().
这里面需要注意的是onStart()、onResume()、onPause()、onStop()这四个函数功能。
onStart():表示Activity正在被启动,即将开始,这时Activity已经可见了,但是还没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity已经显示出来了,但是我们还看不到。
onResume():表示Activity已经可见了,并且出现在前台并且开始活动(获取焦点)。要注意这个和onStart的对比,onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。
onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在特殊情况下,如果这个时候快速地回到当前Activity,那么onResume会被调用。
在这个阶段需要搞懂两个问题:
1. onStart和onResume、onPause和onStop从描述上来看差不多,对于我们来说有什么实质的不同呢?
最大的不同在于:是否获得用户的焦点,也就是能不能和用户交互。
2. 假设当前Activity为A,如果这时用户打开一个新的Activity B,那么B的onResume和A的onPause哪一个先执行
A的onPause执行完后才会执行B的onResume,只有在A的onPause执行完后,才会创建新的B。

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

异常一般会有两种情况:
(1). 资源相关的系统配置发生改变导致Activity被杀死并重新创建。

  • 这里的异常一般是指例如 竖屏到横屏的变化等,在这种异常情况下,系统会调用onSaveInstanceState来保存当前的Activity状态。这个方法的调用时机是在onStop之前,它和onPause没有既定的时序关系。需要强调的一点是,这个方法只会出现在Activity被异常终止的情况下,正常情况下系统是不会回调这个方法。
  • 当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的bundle对象作为参数同事传递给onRestoreInstanceStateonCreate方法。
  • 在异常情况下,系统会默认为我们保存当前Activity的视图结构,并且在Activity重启后为我们恢复这些数据,比如文本框中用于输入的数据、ListView滚动的位置等,这些View相关的状态系统都能够默认为我们恢复。每个View都有onSaveInstanceStateonRestoreInstanceState这两个方法。

(2). 资源内存不足导致低优先级的Activity被杀死。

  • 优先级从高到低依次为:前台Activity、可见但并非前台的Activity和后台的Activity

(3). android:configChanges="..."这个属性可以使系统在特定的场景下部重建,常用的有下面几个选项:

  • local:设备的本地位置发生了变化,一般指切换了系统语言;
  • keyboardHidden:键盘的可访问性发生了变化,比如用户调出了键盘;
  • orientation:屏幕方向发生了变化,比如旋转了手机屏幕。
    配置了android:configChanges="xxx"属性之后,Activity就不会在对应变化发生时重新创建,而是调用ActivityonConfigurationChanged方法。

1.2 Activity启动模式

1.2.1 启动模式

  1. 当栈中没有任何Activity的时候,系统就会回收这个任务栈。
  2. 从非Activity类型的Context(例如,Application、Service等)中以standard模式启动其他的Activity是不行的,这是因为standard模式的Activity默认会进入启动它的Activity所属的任务战中,但是由于非Activity类型的Context并没有所谓的任务栈。但是可以为待启动Activity指定FLAG_ACTIVITY_NEW_TASK标记位。
  3. 任务栈分为前台任务栈和后台任务栈,后台任务栈中的Activity位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。
  4. 参数TaskAffinity,意为任务相关性。这个参数标识了一个Activity所需要的任务栈的的名字,默认情况下,所有Activity所需要的任务栈的名字为应用的包名。TaskAffinity属性主要和SingleTask启动模式或者allowTaskReparenting属性配对使用,在其他情况下没有意义。当TaskAffinitysingleTask启动模式配对使用的时候,它具有该模式的Activity目前任务栈的名字,待启动的Activity会运行在名字和TaskAffinity相同的任务栈中。
    TaskAffinityallowTaskReparenting结合的时候,当一个应用A启动了应用B的某个Activity C后,如果Activity C的allowTaskReparenting属性设置为true的话,点击home到主界面,然后点击应用B,那么当应用B被启动后,系统会发现Activity C所需的任务栈存在了,就将Activity C从A的任务栈中转移到B的任务栈中。
  5. Activity有两种启动模式,一种是通过AndroidMenifest,一种的通过在intent.addFlags()。二者区别:首先,优先级上第二种方式的优先级要高于第一种,当两种同事存在时,以第二种方式为准;其次,上述两种方式在设定范围上有所不同,比如,第一种方式无法直接为Activity设定FLAG_ACTIVITY_CLEAR_TOP标识,而第二种方式无法为Activity指定singleInstance模式。
  6. singleTask模式的具体分析:当一个具有singleTask启动模式的Activity请求启动之后,系统首先会寻找是否存在A想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建Activity的实例把它放到栈中;如果存在Activity所需要的任务栈,这时候要看栈中是否有Activity实例存在,如果有,那么系统就会把该Activity实例调到栈顶,并调用它的onNewIntent方法(它之上的Activity会被迫出栈,所以singleTask模式具有FLAG_ACTIVITY_CLEAR_TOP效果);如果Activity实例不存在,那么就创建Acitivty实例并把它压入栈中。

1.2.2 Activity的Flags

Activity的Flags主要包含有:FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_SINGLE_TOPFLAG_ACITIVTY_EXCLUDE_FROM_RECENTS:具有这个标记的Activity不会出现在历史Activity列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity的时候这个标记比较有用,它等同于属性设置android:excludeFromRecents="true"

IntentFilter的匹配规则

(1). IntentFilter中的过滤信息由action、category、data,为了匹配过滤列表,需要同时匹配过滤列表中的actiion、category、data信息,否则匹配失败。一个过滤列表中的action、category、data可以有多个,所有的action、category、data分别构成不同类别,同一类别的信息共同约束当前类别的匹配过程。只有一个Inten同时匹配action类别、category类别和data类别才算完全匹配,只有完全匹配才能成功启动目标Activity。此外,一个Activity中可以有多个intent-filter,一个Intent只要能匹配任何一组intent-filter即可成功启动对应的Activity。

<intent-filter>
    <action android:name="com.ryg.charpter_1.c" />
    <action android:name="com.ryg.charpter_1.d" />

    <category android:name="com.ryg.category.c" />
    <category android:name="com.ryg.category.d" />
    <category android:name="android.intent.category.DEFAULT" />

    <data android:mimeType="text/plain" />
</intent-filter>

(2). action匹配规则:只要Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功,action匹配区分大小写。
(3). category匹配规则:Intent中如果有category那么所有的category都必须和过滤规则中的其中一个category相同,如果没有category的话那么就是默认的category,即android.intent.category.DEFAULT,所以为了Activity能够接受隐式低啊用,配置多个category的时候必须加上默认的category。
(4). data匹配规则:data的结构很复杂,语法大致如下

<data android:scheme="string"
  android:host="string"
  android:port="string"
  android:path="string"
  android:pathPattern="string"
  android:pathPrefix="string"
  android:mimeType="string" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值