美文网首页学习之鸿蒙&Android
Activity的启动模式、任务栈以及标志位

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

作者: 乌托邦式的爱情 | 来源:发表于2021-06-14 14:41 被阅读0次

    上两篇讲完了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的启动模式呢?

    第一种方式在清单文件里面设置:

    1.png

    第二种在代码里面设置:

    2.png

    这两种方式都可以为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时候清单文件是怎么设置的。

    3.png

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


    4.png

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


    5.png

    看到这里很多童靴会说,怎么这里不用配置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的构成相对来说稍微复杂一点。


    6.png

    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/*才能匹配。具体写法如下所示:

    7.png

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

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

    相关文章

      网友评论

        本文标题:Activity的启动模式、任务栈以及标志位

        本文链接:https://www.haomeiwen.com/subject/hxcoeltx.html