Activity

前言

  • 参考书:Android 开发艺术探索

  • 本篇主要介绍 Activity 的生命周期、启动模式和 Intentfliter 的匹配规则

正文

一、Activity 的生命周期

分两种: 正常情况下和异常情况下的生命周期

1.1 正常情况下的生命周期,从上到下
  • onCreate(): 表示 Activity 正在创建,可以做一些初始化工作。

  • onStart(): 表示 Activity 正在启动,这时 Acticity 已经创建出来了,只是没有出现在前台,用户看不到

  • onResume(): 表示 Activity 已经可见,可以与用户进行交互

  • onPause(): 表示 Acticity 正在停止,此时可以做一些停止动画、存储数据等操作,但是注意不能耗时,因为只有这个方法执行完毕,新的 Activity 的 onResume 才会执行

  • onStop(): 表示 Activity 即将停止,可以做一些重量级的回收工作,但是不能耗时

  • onDestroy(): 表示 Activity 即将被销毁,可以做一些回收工作和资源释放

还有一个 onRestart() 方法,此方法表示 Activity 正在重新启动,一般情况下在 Activity 从不可见到可见状态的时候,会调用此方法,比如说 A 跳转到 B 然后再返回 A

1.2 异常情况下的生命周期
1.2.1 资源相关的系统配置发生改变导致 Activity 被杀死并重新创建

比如说,横竖屏切换的时候,显示的图片资源及布局文件等系统配置发生改变,默认情况下,Activity 会被销毁并重新创建,其生命周期方法如下:

  • 首先会调用 onSaveInstanceState() 方法,做数据保存工作,系统默认为我们保存当前 Activity 的视图结构,并在 Activity 重启后,为我们恢复这些数据,比如 文本框中用户输入的数据,ListView 滚动的位置等,但是如果针对于某个 View 来说,能恢复什么数据,可以看 View 的源码来分析,因为 View 和 Activity 一样,都有 onSaveInstanceState() 方法来保存数据,保存的数据在其参数 Bundle 中

  • 其次,调用 onPause() 、onStop()、onDestory() 方法,注意 onSaveInstanceState() 方法可能在 onPause() 之前调用,也可能在其之后调用。

  • 然后,调用 onCreat() 方法,然后继续调用 onRestoreInstanceState() 方法来为其恢复状态和数据,我们可以根据这两个方法中的参数 Bundle 来判断此 Activity 是否被重建

1.2.2 资源内存不足,导致低优先级的 Activity 被杀死

这种方式与上边的第一种情况保存和恢复数据的方法一致,这里说下 Activity 的优先级,从高到低,如下所示:

  • 前台 Activity ,正在与用户交互,优先级最高

  • 可见,但并非前台 Activity ,比如 Activity 中弹出一个对话框,导致 Activity 可见,但是无法与用户交互

  • 后台 Activity ,已经被暂停的 Activity ,比如执行了 onStop() 方法,优先级最低

另外注意,如果一个进程中没有四大组件运行,那么这个进程将会很快被杀死!

1.2.3 阻止 Activity 重新创建

在 AndroidMenifest.xml 中为 Activity 添加一条 configChanges 属性 :

 android:configChanges="orientation"

常用属性值的含义:

  • locale :设备的本地位置发生了改变,一般指切换了系统语言

  • orientation :设备屏幕发生改变,比如旋转屏幕

  • keyboardHidden :键盘的可访问性发生了改变,比如用户调出了键盘

  • screenSize :屏幕尺寸信息发生改变,常用于旋转屏幕导致的 尺寸信息改变,一般和 orientation 配合使用

  • smallestScreenSize :表示设备的物理屏幕尺寸发生改变,注意指的是物理设备,跟旋转屏幕没关系,比如用户切换到了外部的显示设备,这个不常用。

二、Activity 的启动模式

2.1 四种启动模式
  • standard :标准模式,也是系统的默认模式,每次启动一个 Activity 都会创建一个新实例,不管这个实例是否存在,会一一放入任务栈中,然后按回退键的时候,会按照先进后出的原则,一一退栈!

  • singleTop :栈顶复用模式,如果新创建的 Activity 已经位于任务栈的栈顶了,那么此 Activity 不会被重建,注意这个 Activity 的 onCreat()、onstart() 方法不会被调用,因为它并没有发生改变,但是会回调 onNewIntent(Intent intent) 方法,从而获取 intent 信息。

  • singleTask :栈内复用模式,这是一种单实例模式,只要 Activity 在一个栈中存在,那么多次启动 Activity 都不会重新创建实例,和 singleTop 一样,也会回调其 onNewIntent(Intent intent) 方法,但是需要注意一点,如果栈中有的话,该模式,会把所需要的 Activity 之上的所有 Activity 弹出栈,将需要的这个 Activity 放于栈顶!

  • singleInstance : 它是一种加强版的 singleTask ,它除了具有 singleTask 的所有特性之外,还加强了一点,就是只能单独的位于一个栈中!一个栈只能有一个 Activity

2.2 为 Activity 指定启动模式
  • 第一种,通过 AndroidMenifest.xml 文件中,为其添加属性
android:launchMode="singleTop"
  • 第二种,通过在 Intent 中设置标志位 Flags 来为 Activity 指定模式
Intent intent = new Intent(this,TextActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
  • 两种方式的区别:
  1. 优先级,第二种要高于第一种,两种都存在的话,以第二种为准;
  2. 限定范围不同,第一种无法为 Activity 指定 FLAG_ACTIVITY_CLEAR_TOP 标识,第二种无法为 Activity 指定 singleInstance 模式!
2.3 Activity 的 Flags

Activity 的 Flags 有很多,作用也很多,有些可以设定 Activity 的启动模式,有些可以影响 Acticity 的运行状态,这里记录些比较常用的 Flags

  • FLAG_ACTIVITY_NEW_TASK ,指定 Activity 的启动模式为 singleTask

  • FLAG_ACTIVITY_SINGLE_TOP ,指定 Activity 的启动模式为 singleTop

  • FLAG_ACTIVITY_CLEAR_TOP ,当 Activity 启动时,与其在同一个任务栈并在其上边的所有 Activity 全部出栈,一般和 singleTask 启动模式一块出现

  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS ,在某些情况下,我们不希望用户通过历史列表回到我们的 Activity 的时候,使用这个标记,等同于 xml 文件中的属性: android:excludeFromRecents="true"

三、Activity 中 IntentFilter 匹配规则

  • Activity 的启动方式有两种,显式启动和隐式启动,如果两者都存在那么以显示为主,显式启动很简单,主要记录下隐式启动

  • 隐式启动需要 Intent 能够匹配目标组件的 IntentFilter 中的过滤信息,过滤信息有三个,分别是 action 、 category 、 data,下边针对这三个过滤信息做介绍

3.1 action 的匹配规则
  • action 只是一个字符串,区分大小写,系统中有预定义的一些 action 我们也可以自定义自己所需要的 action, action 可以有多个,但是我们只要匹配成功一个即可匹配成功,需要注意的是,只要是隐式启动,那么 Intent 中必须要有 action
3.2 category 的匹配规则
  • category 也是一个字符串,category 也可以有多个,但是必须要每个都匹配成功才行,另外,如果需要隐式启动,那么必须添加 android.intent.category.DEFAULT 这个 category ,因为我们调用 startActivity 方法的时候,系统会默认为我们添加这个一个 category ,所以必须要添加
3.3 data 的匹配规则
  • data 相对复杂一点,结构如下
<data android:scheme="aaa"
 android:host="aaa"
 android:port="aaa"
 android:path="aaa"
 android:pathPattern="aaa"
 android:pathPrefix="aaa"
 android:mimeType="aaa"/>

主要是有两部分组成 mimeType 和 Uri

  1. mimeType 指媒体类型 例如: image/jpeg vided/* ...
  2. Uri 的结构如下:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]

Uri 的属性介绍如下:

scheme:整个URI的模式,如常见的http,file等,注意如果URI中没有指定的scheme,那么整个uri无效
host:URI的域名,比如我们常见的www.mi.com,www.baidu.com,与scheme一样,一旦没有host那么整个URI也毫无意义;
port:端口号,比如80,很容易理解,只有在URI中指定了scheme和host之后端口号才是有意义的;
path,pathPattern,pathPrefix包含路径信息,path表示完整的路径,pathPattern在此基础上可以包含通配符,pathPrefix表示路径的前缀信息;
  • 只匹配 scheme 的例子如下:
        <activity android:name=".TextActivity">

            <intent-filter>
                <action android:name="111"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
                <data android:scheme="222"></data>
            </intent-filter>

        </activity>
        Intent intent = new Intent();
        intent.setAction("111");
        // scheme:// 固定写法,后边的 111 是自己随便写的
        intent.setData(Uri.parse("222://111"));

        startActivity(intent);
  • 只匹配 mimeType 的例子如下
        <activity android:name=".TextActivity">

            <intent-filter>
                <action android:name="111"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
                <data android:mimeType="image/*"></data>
            </intent-filter>

        </activity>
        Intent intent = new Intent();
        intent.setAction("111");
        // 这种情况,scheme 默认为 content ,亲测 file 会报错
        //注意此处是 setDataAndType 
        intent.setDataAndType(Uri.parse("content://111"),"image/png");
        startActivity(intent);
  • 注意,data,不是必须要添加的,也就是说如果只有 action 和 category 也能匹配成功
  • 还有一点,如果我们要启动系统的页面,如打电话页面,需要找到其匹配规则,进行匹配,然后启动

  • 另外,IntentFilter 可以有多对,只要匹配其中一对即可成功。

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

推荐阅读更多精彩内容