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。此过程是图一紫色箭头所显示的流程。

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

第一种异常情况是指与资源相关的系统配置发生变化,如将手机语言进行更改,或者是手机的屏幕方向发生了改变,都会使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的实例入栈。

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

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

显然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中必须定义

由于所有的隐式启动都会自动加入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。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容