Android 开发艺术探索 - 读书笔记之第一章 Activity 的生命周期和启动模式

1.1 Activity 的生命周期全面分析

1.1.1 典型情况下的生命周期分析

  • onPause: 正在停止,正常情况下紧接着 onStop 就会被调用,然后新的 Activity 执行 onResume; 如果新 Activity 采用了透明主题,则不会调用 onStop,因为 onStop 意味着不可见
  • 按 back 键回退时,回调 onPause -> onStop -> onDestroy
  • 生命周期的配对
    • onCreate 与 onDestroy,创建和销毁
    • onStart 与 onStop,显示与消失
    • onResume 与 onPause,前台与后台
  • 旧的活动 onPause,然后新的活动 onResume

1.1.2 异常情况下的生命周期分析

  1. 资源相关的系统配置发生改变导致 Activity 被杀死并重启(比如横竖屏切换),这时候会在 onDestroy 前调用 onSaveInstanceState,在 onCreate 后调用 onRestoreInstanceState。要注意两点问题:
  • 只有在异常情况(包括第二种情况)下 onSaveInstanceState 和 onRestoreInstanceState 才会被调用
  • onRestoreInstanceState 里的 Bundle 参数无需判空,而 onCreate 的 Bundle 参数就需要。
  1. 内存不足导致低优先级的 Activity 被杀死
    指定在某种情况下,系统不会重启 Activity,可以给 configChanges 属性添加值,常见的有:
项目 含义
locale 切换了系统语言
orientation 屏幕方向变化
keyboardHidden 键盘的可访问性发生了改变,比如用户调出了键盘
screenSize api 13 以上(min 和 target 大于13)屏幕方向切换不会重启,否则重启

1.2 Activity 的启动模式

1.2.1 Activity 的 LaunchMode

四种启动模式,解决了一下几个问题:

  • 单个任务栈下重复创建某个 Activity,创建新的实例还是复用已有的实例
  • Activity 的复用策略,是栈顶复用还是栈内复用
  • 使用 TaskAffinity 属性配置多任务栈,当任务栈中的一个活动被唤醒,任务栈也恢复到前台状态
  1. 标准模式,重新创建目标 Activity,并加入启动它的 Activity 的任务栈中,所以非 Activity 类型的 Context 启动标准模式的 Activity 会报错,这时只要指定 FLAG_ACTIVITY_NEW_TASK 标记位

  2. singleTop,栈顶复用,启动栈顶的 Activity 不会重新创建,且 onNewIntent 方法会被调用

  3. singleTask,栈内复用

  • 如果要启动的 Activity 需要的任务栈(根据 TaskAffinity 属性查找)没有找到,系统会为它创建该任务栈,并将 Activity 放到栈中
  • 如果需要的任务栈存在,且存在该 Activity 的实例,则该 Activity 不会重新创建,且 onNewIntent 方法会被调用; 如果所需的栈中存在该 Activity,可以指定 FLAG_ACTIVITY_CLEAR_TOP 标记位,则该 Activity 上的 Activity 全部出栈。
  • 单独讲讲 TaskAffinity 属性,它标识了一个 Activity 所需要的任务栈的名字,默认(即不配置该属性的话)为应用的包名,通常与 singleTask 模式或 allowTaskReparenting 属性搭配使用:
    • 当与 singleTask 模式配对使用时,如前文所述;
    • 当与 allowTaskReparenting 属性配对使用时,比如当应用 A 启动了 应用 B 的某个 Activity,若该 Activity 的 allowTaskReparenting 设置为 true,则当应用 B 启动时,此 Activity 会直接从应用 A 的任务栈转移到 应用 B 的任务栈中。
  1. singleInstance,单实例模式,启动时系统直接为其创建新的任务栈(无需配置 TaskAffinity),也就是永远不会重复创建该活动的实例

使用 adb shell dumpsys activity 命令查看设备的任务栈

1.2.2 启动 Activity 的 Flags(Intent 的标志位)

通过 intent.setFlags(Intent.FLAG_ACTIVITY_*) 来动态指定启动模式

标记 作用
FLAG_ACTIVITY_NEW_TASK 使用 singleTask 模式
FLAG_ACTIVITY_SINGLE_TOP 使用 singleTop 模式
FLAG_ACTIVITY_CLEAR_TOP 位于它上面的 Activity 出栈,与 singleTask 搭配使用
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 不保留此Activity 的启动历史,等效在 XML 中指定 android:excludeFromRecents="true"

1.3 IntentFilter 的匹配规则

用于 Activity 的隐式启动,例如你点击一个 http url,系统会弹出对话框要你选择使用哪一种浏览器;IntentFilter 的过滤信息有 action,category,data。

<activity android:name=".ui.MainActivity">
  <intent-filter>
      <action android:name="**" />
      <category android:name="**" />
      <data 
          android:scheme="**"
          android:host="**"
          android:port="**"
          android:path="**"
          android:pathPattern="**"
          android:pathPrefix="**"
          android:mimeType="**" />
  </intent-filter>
</activity>
  1. action 表示一个 Activity 能干什么
    比如发送,共享,打电话等等;一个 action 表示一个动作,一个 Intent 中会加入若干个 action,表示它要干什么,没有同时具备这些能力的 activity 会被过滤掉;如果一个 Intent 没有 action,那没人知道它要干什么,也就无法匹配这个 Intent。

  2. category 表示一个 Activity 是什么
    比如可以标记一个 Activity 是地图,浏览器,日历等等;一个 Intent 中不加 category,系统也会给他一个默认的 category,即 category.DEFAULT;其他情况也是与 action 类似的。

  3. data 表示一个 Activity 可以响应那些类型的资源,具体就是 URI;
    别看 data 的属性那么多,其实可以分为两个部分,mimeType 和 URI;一个 URI 的结构就是

<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]

若没有主动指定 URI,那么默认就是 content 和 file,即本地文件。
例如百度的 APP 会对 www.baidu.com 的链接响应,MP3
播放器会对 MP3 格式的文件响应,迅雷下载器会对特定的 URI 响应等等。

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

推荐阅读更多精彩内容