美文网首页
二、Android开发艺术探索之Activity启动模式全解析

二、Android开发艺术探索之Activity启动模式全解析

作者: kim_liu | 来源:发表于2018-10-11 16:29 被阅读33次

    1.Activity的LaunchMode

    为什么会有启动模式一说,当我们创建Activity时,系统会将它们一一放入任务栈中,任务栈是一种“后进先出”的栈结构,也就是最后放入的Activity会在最上面,如果多次启动同一个Activity,系统会反复创建多个实例,这样很多余,所以就有了启动模式这个概念。
    1.standard: 标准模式,系统默认的模式,每次启动一个Activity都会重新创建一个实例,不管这个实例是否已经存在。被创建的实例的生命周期,符合典型情况下的生命周期。

    standard启动模式下启动的Activity,如果使用ApplicationContext的上下文会报错,这是因为standard模式的Activity默认会进入启动它的Activity所属的任务栈中,但是由于非Activity类型的Context(如ApplicationContext)并没有所谓的任务栈。解决这个问题的方法是为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位,这样启动的时候就会为它创建一个新的任务栈,这个时候启动的Activity实际上是以singleTask模式启动的。
    1. singleTop: 栈顶复用模式 。 如果要创建的Activity位于栈顶,那么此Activity不会被重新创建,同时它的onNewIntent()会被调用,这个时候它的onCreate(),onStart(),不会被系统调用,因为没有发生改变。如果要创建的Activity不位于栈顶,仍会被重新创建。

    3.singleTask: 栈内复用模式。单实例模式,只要要创建的Activity在栈内存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调其onNewIntent() 。但是singTask默认具有clearTop效果,所以如果要创建的Activity位于栈内,重新创建时,不在栈顶的话,会导致其上的Activity全部出栈。

    1. singleInstance : 单实例模式。 这是一种加强的singleTask模式,它除了具有singleTask的所有特性之外,还加强了一点,那就是具有此种模式的Activity只能单独的位于一个任务栈中。Activity单独的在这个任务栈中,由于栈内复用的特性,后续的请求均不会创建新的Activity。

    2. 给Activity指定启动模式。

    1. 通过AndroidManifest.xml来指定。

    <activity 
             ......
             android:launchMode = "singleTask"
             .......
              />
    

    2. 在Intent中设置标志位来为Activity指定启动模式。

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    

    Activity的Flags

    1. FLAG_ACTIVITY_NEW_TASK 这个标记位的作用是为Activity指定“singleTask” 启动模式,其效果和在xml中指定该启动模式相同。

    2. FLAG_ACTIVITY_SINGLE_TOP 这个标记位的作用是为Activity指定“singTop”启动模式,其效果和在XML中指定该启动模式相同。

    3.FLAG_ACTIVITY_CLEAR_TOP 具有此标记位的Activity启动时,在同一个任务栈中所有位于它上面的Activity都要出栈,这个标记位一般会和singleTask启动模式一起出现,在这种情况下,被启动的Activity的实例如果已经存在,那么系统会调用它的onNewIntent()。如果被启动的Activity采用standard模式启动,那么它连同它之上的Activity都要出栈,系统会创建新的Activity实例并放入栈中。 而SingTask默认就具有此标记位的效果。

    4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 具有这个标记位的Activity不会出现在历史Activity列表中,当某些情况下我们不希望用户通过历史列表回到我们的Activity时这个标记比较有用。等同于在XML中设置Activity的属性android:excludeFromRecents = "true"。

    Activity的两种启动模式的优先级还是有差别的,第二种方式要高于第一种,当两种同时存在时,以第二种方式为准。但是这两种方式还是有差别的。第一种无法指定FLAG_ACTIVITY_CLEAR_TOP标识,第二种无法为Activity指定singleInstance模式。

    3. IntentFliter的匹配规则。

    启动Activity分为显式调用和隐式调用。显式调用需要明确的指定被启动对象的组件信息,包括类名和包名。也就是intent.setClass(MainActivity.this,SecondActivity.class);

    隐式调用:需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配将无法启动目标Activity。IntentFilter中的过滤信息有action、category、data。

    1.action

    action是一个字符串,action的匹配规则是Intent中的action必须能够和过滤规则中的action匹配,这里说的匹配是指action的字符串值完全一样。一个过滤规则中可以有多个action,那么只要Intent中的action能够和过滤规则中的任何一个action相同即可匹配成功。注意:action是需要区分大小写的。

    2.category

    category是一个字符串,category匹配规则,Intent中如果已经出现了category,不管有几个category,对于每个category来说,它必须是过滤规则中已定义了的category。当然,Intent中可以没有category,系统会给intent默认加上android.intent.category.DEFAULT这个category。

    3.data的匹配规则。

    data的结构:
    <data android:scheme = "string"
              android:host="string"
              android:port="string"
              android:path="string"
              android:pathPattern="string"
              android:pathPrefix ="string"
             android:mimeType="string"/>
    

    data由两部分组成,mimeType和URI。mimeType指媒体类型,如image/jpeg、audio/mpeg4-generic和video/*等。Uri中包括的数据较多,结构如下:

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

    Scheme:URI的模式,比如http、file、content等,如果URI中没有指定scheme,那么URI是无效的。

    Host:URI主机名,比如www.baidu.com,如果host未指定,那么URI是无效的。

    Port:URI的端口号,比如80,仅当URI中指定了scheme和host参数的时候port参数才是有意义的。

    path、pathPrefix、pathPattern表示的是路径信息。

    欢迎关注个人公众号,加入进来一起学习吧!


    平头哥写代码

    相关文章

      网友评论

          本文标题:二、Android开发艺术探索之Activity启动模式全解析

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