Android开发艺术探索之读书笔记一

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

书中作者大体上从两种情况来介绍了Activity的生命周期。第一种是手机运行环境良好不变(屏幕方向不变、内存充足等),用户正常操作APP页面。第二种情况是异常情况下,Activity的生命周期受到了运行环境改变的影响,被系统杀死,Activity的生命周期发生了改变。

在第一种情况中,Activity的生命周期大致如下:

系统调用Activity的onCreate方法创建一个Activity对象,随后调用onStart方法,这时候Activity其实就是可见状态,但还不是可交互状态,接下来会调用onResume方法将其作为前台活动页面,此时Activity的状态是可交互状态,此过程对应的是图一中的绿色箭头所显示的流程。

当出现页面部分被遮挡从而使用户无法与此Activity进行交互时(如:页面中弹出了对话框遮挡住了Activity),Activity的onPause方法就会被调用。如果对话框消失,Activity重新回到前台状态(可交互状态),那么onResume方法会重新被调用。此过程是图一中蓝色箭头所显示的流程。

如果Activity A正处于可交互状态,此时页面跳转到另一个页面Activity B,生命周期函数会依次被调用:Activity A 的onPause----Activity B 的onCreate-------Activity B的onStart------Activity B 的onResume-------Activity A 的onStop。当页面再次回到Activity A的时候,会调用Activity B的onPause-----------Activity A的onRestart-------Activity A的 onStart--------Activity A 的onResume------Activity B的onStop。此过程是图一紫色箭头所显示的流程。

Android开发艺术探索之读书笔记一_第1张图片

在第二种情况中,也分两种异常情况。

第一种异常情况是指与资源相关的系统配置发生变化,如将手机语言进行更改,或者是手机的屏幕方向发生了改变,都会使Activity被重新创建加载,除非Activity中configChanges属性配置了对应的值。在异常情况下,Activity发生被回收重新创建,其onPause、onStop、onDestory方法均被调用。同时在调用onStop方法之前还调用了另一个方法onSaveInstanceState方法将页面的状态进行保存(至于如何对Activity状态进行保存就需要去阅读相关源码才知道,不过书中提到系统是运用了委托机制来进行状态的保存)。在该Activity再次被创建时,系统会调用onRestoreInstanceState方法,并将onSaveInstanceState方法中保存的Bundle对象来作为参数传递给onRestoreInstanceState方法,此过程如图二所示。

第二种异常情况,当手机运行内存不足会导致优先级别较低的Activity所在的进行被杀死。Activity按照优先级别从高到低可以分为:前台交互的Activity优先级别最高、其次是可见但无法交互的Activity、最低级别是处于系统后台被暂停的Activity。在手机内存不足的情况下,系统会优先杀死优先级别低的Activity所在进程。同样的,在此过程中Activity的生命周期跟第一种异常情况是一样的,此过程如图一红色箭头所示。


Activity的启动模式

书中分别介绍了Activity的四种加载模式:standard、singleTop、singleTask、singleInstance。

第一种加载方式相对容易理解,在标准模式下启动,被启动的Activity将会加载到启动它的Activity所在的任务栈中,所以如果被加载的Activity不是由Activity的context来启动加载的,那么就会报错,书中举了ApplicationContext通过标准模式下加载Activity就会报异常这个例子。此模式下Activity如果多次被加载,会出现多个实例。

第二种加载模式singleTop是指栈顶复用。意思就是如果Activity的实例是位于栈顶,再次以栈内复用的方式加载的话,该Activity不会被重新创建出新的实例,而是重复利用已经位于栈顶的实例,所以被重用的实例都会在被重新调用的时候加载它的onNewIntent方法。如果将要被启动的Activity的实例不是位于栈顶,那么还是会被重新创建新的实例。

第三种Activity加载方式singleTask是指栈内复用。栈内复用是指Activity实例所需要的任务栈中已经存在一个将要被加载的Activity的实例,那么该实例将会被复用。同时,如果实例被重用,所有位于该实例顶的实例都会被清出该任务栈,符合clearTop原则。跟singleTask配合使用的还有一个Activity的属性,TaskAffinity。该属性可以指定加载的Activity到哪个任务栈。默认情况下所有的Activity都是加载都以包名相同的任务栈中。

第四种加载模式singleInstance。这是一种比较少用到的模式,在全局中单例模式。意思就是在整个应用中,如果某个Activity以这种方式加载启动,那么系统会新创建一个任务栈,并且创建一个Activity的实例入栈。

Android开发艺术探索之读书笔记一_第2张图片

学完这四种加载模式后,我最后有一个疑问,如果说在标准模式下启动,被启动的Activity将会加载到启动它的Activity所在的任务栈中,那如果从页面MainActivity标准方式跳转到SecondActivity,再通过SinlgeInstance方式加载SingleInstanceActivity,最后在SingleInstanceActivity中通过标准的加载方式加载ThirdActivity,那么ThirdActivity会不会跟SingleInstanceActivity在同一个任务栈中呢?

下图为我自己验证一个过程的结果:

Android开发艺术探索之读书笔记一_第3张图片

显然ThirdActivity不跟SingleInstanceActivity在同一个任务栈,而是在默认的任务栈中。

最后谈到了设置Activity加载模式的方法有两种,一种是通过清单文件来设置,另外一种是通过Java代码中启动跳转的时候设置标示位来实现,两种方式的区别不是很大,但第一种方式无法设置FLAG_ACTIVITY_CLEAR_TOP标识,第二种方法无法为Activity设置singleInstance模式,并且如果两种方式都设置了,那么以第二种方式为主。

Activity的Flags

这部分内容比较少使用到,正常情况下都不需要指定Activity的Flags。书中主要介绍了常见的几种标识:

FLAG_ACTIVITY_NEW_TASK    =====作用等同于启动模式中的singleTask模式

FLAG_ACTIVITY_SINGLE_TOP======作用等同于启动模式中的singleTop模式

FLAG_ACTIVITY_CLEAR_TOP   ======该标识需要FLAG_ACTIVITY_NEW_TASK配合使用。将目标Activity实例所在任务栈中位于该实例上面的所有Activity都被清空退出栈内。意味中singleTask模式就具有FLAG_ACTIVITY_CLEAR_TOP标识

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS=======具有该标识的Activity不会出现历史Activity列表中。该标识等同于Activity属性android:excludeFromRecents=true


IntentFilter的匹配规则

启动Activity的方式包括了显式和隐式,显示启动相对简单,这里主要是讲解如何通过IntentFilter的匹配来隐式启动Activity。在清单文件中,Activity标签中可以包含多个IntentFilter匹配规则。每个匹配规则中都是由action、category、data三个标签来定义规则。只有完全匹配到某一个IntentFilter,才会启动对应的Activity。如何才算完全匹配到呢?在IntentFilter中的所定义的属性都分别满足相应的action、category、data的匹配规则。

1)action的匹配规则:

action的字符串值必须完全一样,区分字母的大小写。如果一个IntentFilter中定义了多个action,intent必须满足其中一个。

2)category的匹配规则:

所有隐式启动Activity都会自动在intent中加入了category值为:android.intent.category.DEFAULT。所以在IntentFilter中必须定义

Android开发艺术探索之读书笔记一_第4张图片

由于所有的隐式启动都会自动加入category,所以可以设置intent的category,也可以不设置。但是如果intent中设置了category,那么就必须跟IntentFilter中的有匹配。

3)data的匹配规则:

data匹配分两部分,mimeType和URI。

mimeType指媒体类型,

而URI包含的字段有:scheme、host、port、path、pathPattern、pathPrefix

data中如果没有设置scheme的值,默认是content或者file。

如果IntentFilter中设置了data,那么intent中就必须设置data并且跟其中某一个data。这里匹配成功是指过滤条件中的部分data出现在Intent中的data。

你可能感兴趣的:(Android开发艺术探索之读书笔记一)