Android 笔记:Activity 二三事

原文地址: http://tianma.space/post/579806496/

本文主要记录一些与 Activity 相关的,并不是很容易弄清楚的点。

Activity 生命周期

先上 Google 官方的图:


Activity 生命周期
  • onCreate():当前 Activity 实例第一次被创建时调用
  • onStart():Activity 不可见到可见 时调用
  • onResume(): Activity 获取焦点,可以进行交互时调用
  • onPause():Activity 失去焦点,无法交互时调用
  • onStop():Activity 完全不可见时调用
  • onDestroy():Activity 即将销毁前调用
  • onRestart():Activity 正在被重新启动时调用

这里又引申出 Activity 相关的三个生存期:

  • 完整生存期: onCreate() -> onDestroy()
  • 可见生存期: onStart() -> onStop()
  • 前台(可交互)生存期: onResume() -> onPause()
     
  • Q:Activity A 启动 Activity B 时,A 的 onPause() 先执行还是 B 的 onResume() 先执行呢?
    A:A 的 onPause() 先执行。
    结论:考虑到只有在当前 Activity 的 onPause() 执行完毕之后,新的 Activity 的 onResume() 才执行,所以,onPause() 中尽量别做重量级操作

异常情况下的生命周期

Activity 异常情况重建过程

这里的 异常情况 主要指以下两种情况:

  1. 系统相关的资源配置发生改变产生的异常:
    如果Activity不作特殊处理,当系统配置发生改变(比如屏幕方向发生改变),Activity就会被销毁并重建,onSaveInstanceState()onRestoreInstanceState() 这两个方法就会在这一过程中被调用。

  2. 内存资源不足导致 Activity 被回收的异常:
    Activity会有优先级分级情况,优先级依次降低:

    • 前台 Acitivty,即正在交互的 Activity
    • 可见但非前台 Activity
    • 不可见后台 Activity

    内存资源不足导致 Activity 被回收,在后续也会通过 onSaveInstanceState()onRestoreInstanceState() 存储和恢复数据。
    没有四大组件在运行的进程很容易被系统杀死,所以,一些后台工作不适合脱离四大组件独自后台运行,最佳实践是依赖 Service 以保证进程有较高的优先级。

Activity 在异常情况下进行重建时,系统会默认对 View 相关的状态进行存储和恢复,具体会恢复特定 View 的什么状态数据需要去查阅源码。也就是说,非 View 相关的数据,需要自行存储和恢复。

针对上面的第一种情况,ActivityconfigChanges 可以指定一些资源配置属性,当这些资源配置发生改变之后,Activity 不会重建,不会调用 onSaveInstanceState()onRestoreInstanceState(),取而代之的是回调 onConfigurationChanged() 方法。最常用的 configChanges 选项有:

  • locale:设备的本地位置发生改变,一般指切换系统语言;
  • orientation:屏幕方向发生改变,比如旋转手机屏幕;
  • keyboardHidden:键盘的可访问性发生改变,比如用户调出键盘。

Activity 启动模式

ActivitylaunchMode 由四种:

  1. standard:默认启动方式,每次启动这样的 Activity 都会生成创建新实例。谁启动以 standardlaunchModeActivity, 该 Activity 就会运行在它的那个任务栈中
  2. singleTop:栈顶复用模式,要启动的 Activity 已经有实例在栈顶,则不会生成新实例,不会调用 onCreate()onStart() 而会调用该 ActivityonNewIntent() 方法;其他情况,参考 standard 模式;
  3. singleTask:栈内复用模式。比如 Activity A 的 TaskAffinity 属性指定的任务栈为 a,当启动 A 时,如果任务栈 a 不存在,则创建 a 任务栈,并创建 Activity A 让其入栈;如果任务栈 a 存在,且 A 实例不存在,则 A 入栈;如果任务栈 a 存在,且 A 实例存在,则清空(pop)在 A 之上的所有 Activity 让 A 置于栈顶,并回调 A 的 onNewIntent() 方法;

    TaskAffinity 即 任务相关性,这个参数标识 Activity 所需要的任务栈的名字,默认情况下,这个值是应用包名。 TaskAffinity 主要和 singleTask 启动模式配对使用,singleTask 启动模式的 Activity 会启动在 TaskAffinity 指定的任务栈中。比如:
<activity
  android:name="com.example.ExampleActivity"
  android:taskAffinity="com.exmple.exampleTask"
  android:launchMode="singleTask"/>
  1. singleInstance:单实例模式。可以看做是特殊的 singleTask 模式,除了具有 singleTask 特性外,此种模式的 Activity 只能单独在一个任务栈。

IntentFilter 匹配规则

IntentFilter 用在 Activity 的隐式调用上,先看 IntentFilter 示例:

<activity android:name="com.example.ExampleActivity">
  <intent-filter>
    <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
  </intent-filter>

  <intent-filter>
    <action android:name="android.intent.action.SEND" />
    <action android:name="android.intent.action.SEND_MULTIPLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="com.example.intent.category.CUSTOM_1" />
    <category android:name="com.example.intent.category.CUSTOM_2" />
    <data android:scheme="http"
      android:host="com.example.com"
      android:port="4000"
      android:path="folder"
      android:mimeType="text/plain" />
    <data android:scheme="content"
      android:host="com.example.project"
      android.port="1080"
      android:path="images"
      android:mimeType="image/*" />
  </intent-filter>
</activity>

可以看出一个 Activity 可以包含多个 IntentFilter,即形成一个 IntentFilter 列表,只要匹配任何一个 IntentFilter 就可以启动该 Activity。而 IntentFilter 中可以包含 actioncategorydata 三元素,只有这三个都匹配成功,整个 IntentFilter 才能匹配成功。

action 匹配规则

Intent 中的 action 必须和 IntentFilter 中包含的 action 之一匹配就可以匹配成功。如果,把 Intent 中指定的 action 看做元素 a,把 IntentFilter 中指定的 action 所构成的集合看成集合 A,则 当 a ∈ A 时, action 匹配成功。

category 匹配规则

  1. 如果 Intent 指定 category,就必须被包含在 IntentFilter 中所指定的 category。如果,Intent 中指定的 category 元素构成集合 A, IntentFilter 中指定的 category 元素构成集合 S,则当 A ⊆ S 时, category 匹配成功;
  2. 如果 Intent 不指定 category, 则默认的 categoryandroid.intent.category.DEFAULT, 也会匹配成功。

data 匹配规则

data 部分由 mimeTypeURI 组成,mimeType 表示媒体类型,比如图片、音频、视频、文本等格式,URI 的结构为:

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

比如:

http://com.example.com:8080/search/info
content://com.example.project:200/folder/subfolder/etc
  • schemeURI 的模式,比如 http、file、content,也可以是自定义字符串,如果没有指定 scheme 的值,则整个 URI 无效;
  • hostURI 的主机名,如果没有指定,则整个 URI 无效;
  • port:端口号;
  • pathpathPrefixpathPattern 分别代表 完整路径匹配、前缀路径匹配、正则路径匹配。

data 的匹配规则跟 action 类似,也就是如果,把 Intent 中指定的 data 看做元素 d,把 IntentFilter 中指定的 data 元素所构成的集合看成集合 D,则 当 d ∈ D 时, data 匹配成功。

如果 data 节点中只指定了 mimeType,那么系统默认的 URIscheme 为 content 和 file。也就是说,在这种情况下,比如 intent 指定的 schemehttp 则会出现 Activity 找不到的异常。

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