您的位置:首页 > 其它

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

2017-01-25 13:09 218 查看

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
对象作为参数同事传递给
onRestoreInstanceState
onCreate
方法。

在异常情况下,系统会默认为我们保存当前Activity的视图结构,并且在Activity重启后为我们恢复这些数据,比如文本框中用于输入的数据、ListView滚动的位置等,这些View相关的状态系统都能够默认为我们恢复。每个View都有
onSaveInstanceState
onRestoreInstanceState
这两个方法。

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

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

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

local
:设备的本地位置发生了变化,一般指切换了系统语言;

keyboardHidden
:键盘的可访问性发生了变化,比如用户调出了键盘;

orientation
:屏幕方向发生了变化,比如旋转了手机屏幕。

配置了
android:configChanges="xxx"
属性之后,
Activity
就不会在对应变化发生时重新创建,而是调用
Activity
onConfigurationChanged
方法。

1.2 Activity启动模式

1.2.1 启动模式

当栈中没有任何
Activity
的时候,系统就会回收这个任务栈。

从非
Activity
类型的
Context
(例如,Application、Service等)中以
standard
模式启动其他的
Activity
是不行的,这是因为
standard
模式的
Activity
默认会进入启动它的
Activity
所属的任务战中,但是由于非
Activity
类型的Context并没有所谓的任务栈。但是可以为待启动Activity指定
FLAG_ACTIVITY_NEW_TASK
标记位。

任务栈分为前台任务栈和后台任务栈,后台任务栈中的
Activity
位于暂停状态,用户可以通过切换将后台任务栈再次调到前台。

参数
TaskAffinity
,意为任务相关性。这个参数标识了一个
Activity
所需要的任务栈的的名字,默认情况下,所有Activity所需要的任务栈的名字为应用的包名。
TaskAffinity
属性主要和
SingleTask
启动模式或者
allowTaskReparenting
属性配对使用,在其他情况下没有意义。当
TaskAffinity
singleTask
启动模式配对使用的时候,它具有该模式的
Activity
目前任务栈的名字,待启动的Activity会运行在名字和
TaskAffinity
相同的任务栈中。

TaskAffinity
allowTaskReparenting
结合的时候,当一个应用A启动了应用B的某个
Activity
C后,如果
Activity
C的
allowTaskReparenting
属性设置为true的话,点击home到主界面,然后点击应用B,那么当应用B被启动后,系统会发现
Activity
C所需的任务栈存在了,就将Activity C从A的任务栈中转移到B的任务栈中。

Activity
有两种启动模式,一种是通过AndroidMenifest,一种的通过在intent.addFlags()。二者区别:首先,优先级上第二种方式的优先级要高于第一种,当两种同事存在时,以第二种方式为准;其次,上述两种方式在设定范围上有所不同,比如,第一种方式无法直接为Activity设定
FLAG_ACTIVITY_CLEAR_TOP
标识,而第二种方式无法为Activity指定
singleInstance
模式。

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_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
FLAG_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" />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐