Activity的生命周期和启动模式

来源:互联网 发布:python if else 简写 编辑:程序博客网 时间:2024/06/09 17:48

2016年6月份就买了任玉刚同志的《Android开发艺术探索》这本书,通过目录我就知道这是一本非常不错的Android书籍,并且非常适合像我这种急需晋级的Android开发者。但这半年来也就随便翻了几章,一直没耐心看下去。但今天重新拾掇起来看,感觉受益匪浅。因此,我觉得我一定要耐心把这本书看完,并理解里面的知识点与思想,对每一章的重点再做一个总结,至于总结的好不好,仁者见仁,智者见智。虽然今天这个内容百度上一搜一大把,但我还是喜欢自己看完书后自己做总结,呵呵。下面是书中第一章的总结,标题也是直接引用书中的。

Activity的生命周期

1.典型情况:是指在有用户参与下Activity所经过的生命周期的改变
2.异常情况:是指Activity被系统回收或者由于当前设备的配置发生改变从而导致Activity被销毁重建

典型情况

从onCreate–>onStart–>onResume–>onPause–>onStop–>onDestroy,外加一个onRestart。从整个生命周期来讲,onCreate与>onDestroy是相对,分别标识着Activity的创建与销毁,都只有一次调用;从Activity是否可见来说,onPause与onStop是配对的,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方法可能会被调用多次;从Activity是否在前台来说,onResume与onPause是相对的,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方法可能会被调用多次;

异常情况

A:资源相关的系统配置发生改变导致Activity被杀死并重新创建,当系统配置发生改变后,Activity会被销毁,并调用onPause->onStop–>onDestroy,同时由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存Activity的状态,它既可能在onPause之前调用,也可能在onStop之后调用,他们没有既定的时序关系。当Activity被重新创建的时候,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。
B:资源内存不足导致低优先级的Activity被杀死,Activity的优先级又分为一下几种。
(1)前台Activity(正在和用户交互的Activity),优先级最高。
(2)可见但非前台Activity,比如Activity中弹出了一个对话框,导致了Activity可见但是位于后台无法和用户直接交互。
(3)后台Activity,以及被暂停的Activity,比如执行了onStop,优先级最低。

注意:Android官方文档对onPause的解释有这么一句:不能在onPause中做重量级的操作,因为必须onPause执行完成以后新Activity才能执行onResume。(Activity A开启另外Activity B:(A)onPause–>(B)onCreate–>onResume–>(A)onStop)

Activity的启动模式

1.standard(默认模式)
2.singleTop(栈顶复用模式)
3.singleTask(栈内复用模式)
4.singleInstance(单实例模式)

standard

系统默认的启动模式,每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。这是一个典型的多实例实现,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈,在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那个Activity所在的栈中。

singleTop

在这种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会被回调,通过此方法的参数我们可以提取当前请求的信息。

singleTask

这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调onNewIntent。比如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,就重新创建一个任务栈,然后创建A的实例后把A放入到栈中;如果有实例存在,那么系统就会把A调到栈顶并调用它的onNewIntent方法。同时由于singleTask默认具有clearTop的效果,会导致栈内所有在它上面的Activity全部出栈。

singleInstance

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

注意:在singleTask启动模式中,多次提到某个Activity所需的任务栈,那么什么是Activity所需要的任务栈呢?还要从一个参数说起:TaskAffinity(任务相关性),这个参数标识了一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。当然,我们可以为每个Activity都单独指定TaskAffinity属性,这个属性值必须不能和包名相同,否则就相当于没有指定。TaskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配对使用,在其他情况下没有意义。另外,任务栈分为前台任务栈和后台任务栈,后台任务栈中的Activity处于暂停状态,用户可以通过切换将后台任务栈再次调到前台。

指定Activity的启动模式

1.通过AndroidMenifest为Activity指定启动模式
2.通过在Intent中设置标志位来为Activity指定启动模式

这两种方式的区别:在优先级上,第二种方式的优先级要高于第一种,当两种同时存在时,以第二种方式为准;他们在限定范围上有所不同,第一种无法直接为Activity设定Flag_activity_clear_top(Activity的运行状态)标识,第二种方法无法为Activity指定singleInstance模式。

Activity常用的标记位(Flags)

1.FALG_ACTIVITY_NEW_TASK:为Activity指定singleTask模式,其效果和在XML中指定该模式相同
2.FLAG_ACTIVITY_SINGLE_TOP:为Activity指定singleTop模式,其效果和在XML中指定该模式相同
3.FLAG_ACTIVITY_CLEAR_TOP:具有此标记位的Activity(不能通过配置实现标记),当它启动的时候,在同一个任务栈中所有位于它上面的Activity都要出栈。这个标记位一般会和singleTask启动模式一起出现,在这种情况下,被启动Activity的实例如果已经存在,那么系统就会调用它的onNewIntent。如果被启动的Activity采用standard模式启动,那么它连同它之上的Activity都要出栈,系统会创建新的Activity实例并放入栈顶。
4.FALG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有这个标记的Activity不会出现在历史Activity的列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity的时候这个标记比较有用。它等同于XMl中指定Activity的属性android:excludeFromRecents=”true”。

Activity中IntentFilter的匹配规则

1.显式调用:要明确地指定被启动对象的组件信息,包括包名和类名。
2.隐式调用:不需要明确的指定组件信息

注意:原则是一个Intent不应该既是显式调用又是隐式调用,如果二者共存的话,以显式调用为主。

重点讲隐式调用:隐式调用需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配将无法启动目标Activity。IntentFilter中的过滤信息有action、category、data。
action的匹配规则:action是一个字符串,action的匹配要求Intent中的action存在并且必须和过滤规则中的其中一个action相同,需要注意它和category匹配规则的不同。
category的匹配规则:category是一个字符串,category的匹配规则和action不同,它要求Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同,同时为了我们的Activity能够接收隐式调用,就必须在Intent-Filter中指定”android.intent.categroy.DEFAULT”这个category。
data的匹配规则:data的匹配规则和action类似,如果过滤规则中定义了data,那么Intent中必须也要定义可匹配的data。

0 0