Activity的启动模式、任务栈以及标志位

上两篇讲完了Activity的生命周期的情况,接下来我们继续揭秘Activity其他神秘的面纱,首先我们先来看看关于Activity的启动模式。

在讲解Activity的启动模式之前,我们先来设想一个场景:每当我们启动一个Activity的时候,系统会自动帮我们在当前Activity所属的任务栈里面创建这个Activity并置入栈中,多点几次则系统会自动创建几个,这样的设计里面好像有点傻傻的,因为很多时候我们并不想重复创建,只想要一个能够反复调用。为了解决这个问题,系统推出了Activity的启动模式来解决。首先,我们来看看Activity的启动模式有哪些。

Activity的启动模式:

(1)standard:标准模式。这是系统默认的模式,当我们开启一个Activity的时候,系统会自动帮我们创建好这个实例并将其置于栈顶。其遵循的是后进先出的原则,当我们不停的按返回键的时候,系统会自动一一将位于栈顶的Activity移出,直到当该任务栈不再包含任何Activity实例的时候,系统会自动回收当前的任务栈。

(2)singleTop:栈顶复用模式。如果新的Activity位于栈顶的时候,那么此Activity不会被重新创建,而是调用该Activity的onNewIntent()方法。但是如果新的Activity不位于栈顶的时候,即便在当前的任务栈中已经包含了该Activity,系统依然会重新创建该Activity并置于栈顶。

(3)singleTask:栈内复用模式。这是一种单实例模式,在这种模式下,只要Activity在一个栈中存在,系统就不会创建该实例,而是调用其onNewIntent方法。需要强调的是,当使用这种模式的时候,系统会自动将该Activity置于栈顶,该Activity之上的所有Activity会被自动移出。

(4)singleInstance:单实例模式。这是一种加强版的singleTask,它除了具有singleTask的所有特性外,还加强了一点,即是凡是这种模式的Activity只能单独的位于一个任务栈中。换句话说在该任务栈中只会存在着这一个实例。

现在我们来模拟几种情况:

A、B、C三个Activity

(1)A、B、C都为standard,从A->B->C->C,此时任务栈应该是ABCC
(2)A、B为standard,C为singTop,从A->B->C->C,此时任务栈应该是ABC
(3)A、B为standard,C为singTask,从A->B->C->C,此时任务栈应该是ABC
(4)A、C为standard,B为singTop,从A->B->C->B,此时任务栈应该是ABCB
(5)A、C为standard,B为singTask,从A->B->C->B,此时任务栈应该是AB
当然,具体的实际情况还会不断变化,需要根据实际情况来判断,但是只要你彻底掌握了
Activity的启动模式,相信这个难不倒你。

那么,如何设置Activity的启动模式呢?
第一种方式在清单文件里面设置:
在这里插入图片描述

第二种在代码里面设置:
在这里插入图片描述

这两种方式都可以为Activity指定启动模式,但是二者还是有区别的。首先,在优先级上,第二种比第一种的优先级要高,当两种同时存在时,以第二种为主。其次,两种方式在限定范围上也有所不同。

Activity的任务栈:

在前面讲解启动模式的时候,我们不停的会听到一个新的词汇——任务栈。其重要性不言而喻,那么,到底什么是任务栈呢?这要从一个参数说起:TaskAffinity,可以翻译为任务相关性,这个参数标识了一个Activity所需要的任务栈的名称,默认情况下为应用的包名。当然,我们可以单独为每个Activity指定TaskAffinity这个属性,注意,其值不能和包名相同,否则相当于没有指定。TaskAffinity属性主要和singleTask启动模式配合使用,其他情况下没有意义。另外,任务栈分为前台任务栈和后台任务栈,后台任务栈中的Activity处于暂停状态,用户可以通过切换将后台任务栈置于前台。

Activity的标记位:

Activity的Flag很多,但是在实际的开发过程中我们很少会用到这些标志位,所以,对于此部分的内容以了解并简单使用为主,现在我们就来看看常见的几种标志位。
FLAG_ACTIVITY_NEW_TASK
这个标记位的作用是为Activity指定“singleTask”启动模式,和在清单文件里面设置android:launchMode=”singleTask”相同。

FLAG_ACTIVITY_SINGLE_TOP
这个标记位的作用是为Activity指定“singleTop”启动模式,和在清单文件里面设置android:launchMode=”singleTop”相同。

FLAG_ACTIVITY_CLEAR_TOP
具有此标记位的Activity,当它启动时,意味着在同一个任务栈中所有位于它之上的Activity都要出栈。这个模式一般情况下和FLAG_ACTIVITY_CLEAR_TASK配合使用,在这种情况下,被启动的Activity的实例如果存在,则会直接调用该Activity的onNewIntent方法,但是如果
被启用的Activity的启动模式是standard,那么它连同它上面的activity都要出栈,系统会重新创建新的Activity并置于栈顶。

IntentFilter的匹配原则:
启动activity分为两种,隐式调用和显式调用。显式调用相对来说比较简单,需要指定启动对象的组件信息,包括包名和类名。而隐式调用则不需要明确指定组件信息。二者的优先级上显式调用高于隐式调用。那么,隐式调用又是如何去匹配对应的activity的呢?我们先来看看APP打开首页的activity时候清单文件是怎么设置的。
在这里插入图片描述

你是不是从来没有关注过启动页的清单文件配置信息,其实看到这里我们不难发现,启动页是最明显的隐式调用,至于启动页到底是怎么匹配的不是我们关注的重点,我们关注的是通过intentFilter就可以隐式调用activity。IntentFilter的匹配中的过滤信息有action、category、data。我们先来看一个简单的例子:
在这里插入图片描述

首先在我们的清单文件里面配置好过滤信息,注意,action和category必须同时存在,否则系统找不到对应的activity。紧接着在类里面配置action
在这里插入图片描述

看到这里很多童靴会说,怎么这里不用配置category,其实系统已经默认帮我们添加了只是我们不知道而已,这里就不展开说了。为了匹配过滤列表,需要同时匹配过滤中的action、category、data信息,否则匹配失败。一个过滤列表中的action、categroy、data可以有多个,所有的action、categroy、data构成不同类别,同一类别的信息共同约束当前类别的匹配过程。只有一个Intent同时匹配action、category、data类别才算完全匹配,只有完全匹配才能启动目标activity。需要注意的是,一个activity可以在清单文件里面配置多组过滤信息,而启动activity只需要满足其中中的一组即算匹配成功。

1》action的匹配原则
action的匹配原则要求设置的action与在清单文件里面设置的完全一样,包括大小写,注意,intentFilter中可以配置多个action,只需要满足其中的一个就算成功。

2》category匹配原则
category的匹配原则和action不同,它要求如果intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。

3》data的匹配原则和action类似,如果过滤规则中定义了data,那么intent中也必须要定义可匹配的data。在介绍data的匹配原则之前,我们先来认识一下data的构成,因为data的构成相对来说稍微复杂一点。

在这里插入图片描述

data由两部分组成:mimeType和URI。mimeType指媒体类型,比如image/jpeg、audio/mpeg4-generic、video/*等,可以表示图片、文本和视频等不同的媒体形式。而URI中包含的数据就比较多了,下面是URI的结构:

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

Scheme:URI的模式,比如http、file、content。如果URI中没有指定scheme,意味着URI无效。

Host:URI的主机名,比如www.baidu.com。如果URI中没有指定host,意味着URI无效。

Port:URI的端口号,比如8080,仅在scheme和host指定的情况下才有意义。

Path、pathPrefix、pathPattern表示路径信息。Path对应的是完整的路径信息;pathPattern也表示的是完整的路径信息,但是允许其中包含通配符。pathPrefix表示路径的前缀信息。

讲完了data的基本构成,现在我们再回过头来看看data到底是怎么匹配的呢?

<data android:mimeType="image/*"/>

这种规则指定了媒体类型为所有类型的图片,那么Intent中的mimeType属性必须为image/*才能匹配。具体写法如下所示:
在这里插入图片描述

当然,data的匹配远比我列举的例子复杂,但是其核心原理是一样的。接下来的就是多尝试多琢磨就好。

关于activity的基础篇到这里就结束了,欢迎大家在下面留言~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值