《Android艺术开发探索》学习笔记之Activity的生命周期

《Android开发艺术探索》这本书真心不错,是非常不错的Android开发的进阶书籍,内容深入浅出,推荐大家看一下。

上图就是Activity生命周期切换过程图。

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

1)onCreate:Activity正在被创建,在这方法中做一些初始化的工作。

2)onRestart:Activity正在重新启动,调用情况:当当前的Activity从不可见重新变为可见状态时被调用,如用户按下home键,接着又回到该Activity。

3)onStart:Acitivity正在被启动,即将开始,这是Activity可见,但还没有出现在前台,无法与用户交互,用户看不到。

4)onResume:Activity已经可见并且出现在前台,可以与用户交互。注意和OnStart的区别,onStart和onResume都可见,但onStart在后台,onResume在前台。

5)onPause:Activity正在停止,在此方法中可以做一些数据存储、停止动画等工作,但是注意不能太耗时,因为会影响到新Activity的显示,先执行完onPause,才执行新Activity的onResume方法。

6)onStop:Activity即将停止,可做一些稍微重量级的回收工作,但不能太耗时。

7)onDestroy:Activity生命周期最后一个方法,Activity即将被销毁,可做一些回收工作和最终的资源释放。

Activity生命周期的附加说明

1)针对一个特定的Activity,第一次启动,回调:onCreate—>onStart—>onResume

2)当用户打开新的Activity或者切换到桌面时,回调:onPause—>onStop。特殊情况:新Acitivity采用透明主题,则当前Activity不会回调onStop;

3)当用户再次回到原Activity时,回调:onRestart—>onStart—>onResume;

4)当用户按back键回退时,回调:onPause—>onStop—>onDestroy;

5)当Activity被系统回收后再次打开,生命周期方法回调过程跟(1)的一样,这是生命周期方法一样,不代表所有过程一样。

6)从整个生命周期来说,onCreate和onDestroy时配对的,即Activity的创建和销毁,并且只有可能一次调用,从Activity是否可见来说,onStart和onStop是配对的,从Activity是否在前台来说,onResume和onPause是配对的,随着用户操作或者设备屏幕的点亮和熄灭,onStart、onStop、onResume和onPause可能被多次调用。

异常情况下,Activity的生命周期

1、资源相关的系统配置发生改变导致Activity被杀死并重新创建,比如横屏手机和竖屏手机切换。

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

可以看到被销毁时,系统会调用onSaveInstanceState方法保存当前的Activity状态,这个方法在onStop之前调用,但是和onPause没有既定的时序关系。 当被重新创建时,系统会调用onRestoreInstanceState,并且把销毁时在onSaveInstanceState方法所保存的bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法,我们通过这两个方法判断Activity是否被重新创建,如果重建了,就利用取出并数据并且恢复,onRestoreInstanceState在onStart之后被调用。

在onSaveInstanceState和onRestoreInstanceState方法中,系统会自动帮我们做一些恢复的工作,如当前Activity的视图结构:例如文本框中用户输入的数据,listview滚动的位置等等。

系统保存和恢复的工作流程:activity被意外终止时,调用onSaveInstanceState保存数据,然后activity会委托window去保存数据,接着window再委托它上面的顶级容器去保存数据。顶级容器是一个ViewGroup,很有可能是DecorView。最后顶级容器再一一通知子元素来保存数据,这样子整个数据保存过程就完成了。这是一种典型的委托思想,上层委托下层,父容器委托子元素去处理一件事情。

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

Activity按照优先级分为三种: 1)前台Activity——正在和用户交互的Activity,优先级别最高。

2)可见但非前台Activity——比如Activity弹出一个对话框,导致Activity可见但是位于后台无法和用户交互。

3)后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低。

当内存不足时,系统会按照上述优先级杀死目标的Activity所在的进程。并且通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。如果一个进程没有四大组件在执行就容易被系统杀死,因此,一些后台工作不适合脱离四大组件而独自运行在后台,比较好的方法就是后台工作放入Service中从而保证进程有一定的优先级,这样不容易被系统杀死。

防止Activity因系统配置发生改变而重新创建:

android:configChanges="orientation"
复制代码

具体可以参考表格

Activity的启动模式

1)standard:标准模式,即默认模式,每次启动一个Activity都会创建一个Activity实例,不管这个实例是否存在。这是一种多实例实现,一个任务栈可以创建多个实例,每个实例也可以属于不同的任务栈,谁启动了这个Activity,那么这个Activity就会运行在启动它的那个Activity所在的任务栈。

2)singleTop:栈顶复用模式,即如果新的Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法被回调,通过此方法的参数我们可以取出当前请求的信息,但此Activity的onCreate、onStart不会被系统调用,因为他们并没有发生改变。

3)singleTask:栈内复用模式,这是一种单实例模式,在此模式下,只要Activity存在于任务栈中,启动此Activity就不会重新被创建实例,和singleTop一样,系统会回调其onNewIntent方法。

例子:任务栈S1、S2 1、S1:ABC 启动 D ,D属于S2, 创建S2,D加入S2

2、S1:ABC 启动D,D属于S1 则S1:ABCD

3、S1:ADBC 启动D, D属于S1 则S1:AD

4)singleInstance:单实例模式,这是一种加强的singleTask模式,除了具有singleTask模式的特性外,还加强了一点:具有此模式的Activity只能单独位于一个任务栈中。比如:Activity A是singleInstance模式,当A启动后,系统为它创建新的任务栈,然后A独自在新的任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity,除非系统销毁此任务栈。

Activity的Flags

Activity的Flags,即标志位,作用很多,有的标志位可以设定Activity的启动模式。

常用的标志位:

FLAG_ACTIVITY_NEW_TASK

指定Activity的启动模式为:singleTask

FLAG_ACTIVITY_SINGLE_TOP

指定Activity的启动模式为:singleTop

FLAG_ACTIVITY_CLEAR_TOP

具体此标志位的Activity,当启动它时,在同一个任务栈中所有位于上面的Activity都要出栈,这个模式一般需要和FLAG_ACTIVITY_NEW_TASK配合使用。

FLAG_ACTIVITY_EXCLUDE_FROM_ RECENTS

具有这个标记的Activity不会出现在历史的Activity列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity的时候这个标记比较有用。它等同于在XML中指定Activity的属性android:excludeFromRcents = "true"。

IntentFilter的匹配规则

启动Activity方式:显式和隐式。

显式调用:明确指定被启动对象的组件信息,包括包名和类名。 隐式调用:不需要明确指定组件信息,需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配则无法启动目标组件Activity。IntentFilter中过滤的信息有action、category、data。

<activity android:name=".IntentFilterActivity">
            <intent-filter>
                <action android:name="com.uipro.action.c"/>
                <action android:name="com.uipro.action.d"/>
                <category android:name="com.uipro.category.a"/>
                <category android:name="com.uipro.category.b"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:mimeType="text/plain"/>
            </intent-filter>
        </activity>
复制代码

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

1、action匹配规则

action是一个字符串,系统预定义了一些action,同时也可以在应用中定义自己的action。action的匹配规则是Intent中的action必须能够和过滤规则中的action匹配,这里说的匹配是指action的字符串值完全一样。一个过滤规则中可以有多个action,只要Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功。action区分大小写。

2、category的匹配规则

category是一个字符串,系统预定义了一些category,同时也可以定义自己的category。

匹配规则:category要求Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同,换句话说,Intent中如果出现了category,不过有几个category,对于每个category来说,它必须是过滤规则中已经定义l的category。当然Intent中可以没有category,如果没有category,按照上面的描述,这个Intent仍然匹配成功。

和action区别:action要求Intent中必须有一个action且必须能够和过滤规则中的某个action相同;category要求Intent中可以没有category,但是如果一旦有category,不管几个 ,每个都要能够和过滤规则中的任何一个category相同。

不设置category也能匹配成功的原因:系统在调用startActivity或者startActivityForResult的时候默认为Intent加上android:intent.category.DEFAULT这个category,所以这个category就可以匹配前面的过滤规则中的第三个category。同时过滤规则中就必须指定android:intent.category.DEFAULT

3、data的匹配规则

data的匹配规则和action类似,如果过滤规则中定义了data,那么Intent中也必须要定义可匹配的data。data的语法定义如下:

mimeType:媒体类型,如:image/jpeg,video/*,可以表示图片、文本、视频等不同的媒体格式。

URI结构:

Scheme:URI模式,比如http、file、content等。如果URI没有指定scheme,则URI无效。

Host:URI主机名,比如www.baidu.com。如果不指定Host,URI无效。

Port:URI的端口号,比如80,当且仅当URI指定了scheme和host之后才有意义。

Path、pathPattern和pathfix:都是指路径信息,path表示完整路径信息,pathPattern也是表示完整路径,但可包含通配符,pathfix表示路径的前缀信息。

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

源码可知:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值