Activity 启动模式

 

       在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。这需要为Activity配置特定的加载模式,而不是使用默认的加载模式。

      Activity有四种加载模式,在AndroidManifest.xml文件中activity元素的android:launchMode属性进行配置:

                                 standard       singleTop       singleTask      singleInstance

    这四种模式又分为两类,standardsingleTop属于一类,singleTasksingleInstance 属于一类,他们主要有以下不同

 

1、如何决定所属Task

      Standard 和 singleTop 的activity的目标task和收到的Intent的发送者在同一个Task内。除非intent包括参数FLAG_ACTIVITY_NEW_TASK。而且如果提供了FLAG_ACTIVITY_NEW_TASK参数,会启动到别的Task里。

singleTask和singleInstance 总是把Activity作为一个task的根元素,他们不会被启动到一个其他的task里。

 

2、是否允许多个实例

      Standard 和 singleTop 可以被实例化多次,并且存在于不同的task中,且一个task可以包括一个Activity的多个实例。

      singleTask和singleInstace则限制只生成一个实例,并且是task的根元素。

     singleTop要求如果创建intent的时候栈顶已经有要创建的Activity的实例,则将Intent发送给该实例,而不发送给新的实例

 

3、是否允许其它activity存在于本Task内

     singleInstance 独占一个task,其它activity不能存在那个task里,如果它启动了一个新的avtivity,不管新的Activity的lanuch mode如何,新的Activity都将会得到别的task里运行(如同加FLAG_ACTIVITY_NEW_TASK参数)

另外三种模式。则可以和其它Activity共存。

 

4、是否每次都生成新实例

     standard对于每一个启动Intent都会生成一个Activity的新实例。

    singleTop的avtivity如果在task的栈顶的话,则不生成新的该实例。

    singleInstace是其所在栈的唯一Activity,它会每次都被重用。

    singleTask如果在栈顶,则接受Intent,否则,该Intent会被丢弃,但是访Task仍会回到前台。

 

Lanuch Mode

是否允许多个实例

是否每次都生成新实例

是否允许其他Activity存在于本Task内

如何决定所属Task

standard

可以被多次实例化,同一个Activity中的不同实例可以存在于不同的Task中,同一个Task也可以存在多个Activity实例

允许

存放于StartActivity()的Task。除非设置FLAG_ACTIVITY_NEW_TASK标识

singleTop

同Standard

如果寄存Activity的栈顶为该Activity,则直接用该Activity实例;否则创建新实例

允许

同Standard

singleInstace

不能有多个实例,由于该模式下Activity总是存在于栈顶,所以Activity在同一实例里至多只有一个实例

只有在第一次才创建新的实例,其他情况复用该Activity

允许。如果存放singleTask的寄存Task内,相应一个工Intent时,如果singleTask位于栈顶,则处理Intent,否则会丢失Intent,但该Task会处于前台

存放新的Task内,并且位于该Task的根,不会存放于其他的Task。

singleTask

同singleTask

同singleTask

不允许

同singleTask

 

    standard: 标准模式,一调用startActivity()方法就会产生一个新的实例。

    singleTop: 如果已经有一个实例位于Activity栈的顶部时,就不产生新的实例,而只是调用Activity中的newInstance()方法。如果不位于栈顶,会产生一个新的实例。

    singleTask: 会在一个新的task中产生这个实例,以后每次调用都会使用这个,不会去产生新的实例了。

    singleInstance: 这个跟singleTask基本上是一样,只有一个区别:在这个模式下的Activity实例所处的task中,只能有这个activity实例,不能有其他的实例。

 

下面是影响加载模式的一些特性

1.核心的Intent Flag有:

     FLAG_ACTIVITY_NEW_TASK

     FLAG_ACTIVITY_CLEAR_TOP

     FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

     FLAG_ACTIVITY_SINGLE_TOP

 

 如应用中的操作:

        FLAG_ACTIVITY_CLEAR_TOP     FLAG_ACTIVITY_REORDER_TO_FRONT     FLAG_ACTIVITY_SINGLE_TOP

         

如果已经启动了四个Activity:A,B,C和D。在D Activity里,我们要跳到B Activity,同时希望C finish掉,可以在startActivity(intent)里的intent里添加flags标记,如下所示:

 

             Intent intent = new Intent(this, B.class);

             intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

             startActivity(intent);

 

   这样启动B Activity,就会把D,C都finished掉,如果你的B Activity的启动模式是默认的(multiple) ,则B Activity会finished掉,再启动一个新的Activity B。

   如果不想重新再创建一个新的B Activity,则在上面的代码里再加上:

            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

 

 这样B Activity就会再创建一个新的了,而是会重用之前的B Activity,同时调用B Activity的onNewIntent()方法。

 

 如果已经启动了四个Activity:A,B,C和D,在D Activity里,想再启动一个Actvity B,但不变成A,B,C,D,B,而是希望是A,C,D,B,则可以像下面写代码:

 

               Intent intent = new Intent(this, MainActivity.class);  

              intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);     

Activity的加载模式受启动Activity的Intent对象中设置的Flag和manifest文件中Activity的元素的特性值交互控制。

 

 如果当前活动采用非多重启动模式(如singleTop),或意图有Intent.FLAG_ACTIVITY_SINGLE_TOP标志设置,那么当前活动将继续运行,Activity.onNewIntent()方法调用。
   

 如果新的意图是与前一个相同,而新的意图没有Intent.FLAG_ACTIVITY_CLEAR_TOP设置,那么当前的活动将继续运行原样。否则,目前的活动将结束,一个新的开始

 

2.核心的特性有:

     taskAffinity

     launchMode

     allowTaskReparenting

     clearTaskOnLaunch

    alwaysRetainTaskState

    finishOnTaskLaunch

 

常用:android:allowTaskReparenting

    用法<application android:allowTaskReparenting="true/false"></application>

    是否允许activity更换从属的任务,比如从短信息任务切换到浏览器任务。用来标记Activity能否从启动的Task移动到有着affinity的Task(当这个Task进入到前台时)—— “true”,表示能移动,“false”,表示它必须呆在启动时呆在的那个Task里。

    如果这个特性没有被设定,设定到<application>元素上的allowTaskReparenting特性的值会应用到Activity上。默认值为“false”。

    一般来说,当Activity启动后,它就与启动它的Task关联,并且在那里耗尽它的整个生命周期。当当前的Task不再显示时,你可以使用这个特性来强制Activity移动到有着affinity的Task中。典型用法是:把一个应用程序的Activity移到另一个应用程序的主Task中。

    例如,如果e-mail中包含一个web页的链接,点击它就会启动一个Activity来显示这个页面。这个Activity是由Browser应用程序 定义的,但是,现在它作为e-mail Task的一部分。如果它重新宿主到Browser Task里,当Browser下一次进入到前台时,它就能被看见,并且,当e-mail Task再次进入前台时,就看不到它了。

    Actvity的affinity是由taskAffinity特性定义的。Task的affinity是通过读取根Activity的affinity 决定。因此,根据定义,根Activity总是位于相同affinity的Task里。由于启动模式为“singleTask”和 “singleInstance”的Activity只能位于Task的底部,因此,重新宿主只能限于“standard”和“singleTop”模 式。

android:alwaysRetainTaskState

    用法<activity android:alwaysRetainTaskState="true/false"></activity>

    用来标记Activity所在的Task的状态是否总是由系统来保持——“true”,表示总是;“false”,表示在某种情形下允许系统恢复Task 到它的初始化状态。默认值是“false”。这个特性只针对Task的根Activity有意义;对其它Activity来说,忽略之。
    一般来说,特定的情形如当用户从主画面重新选择这个Task时,系统会对这个Task进行清理(从stack中删除位于根Activity之上的所有Activivity)。典型的情况,当用户有一段时间没有访问这个Task时也会这么做,例如30分钟。
    然而,当这个特性设为“true”时,用户总是能回到这个Task的最新状态,无论他们是如何启动的。这非常有用,例如,像Browser应用程序,这里有很多的状态(例如多个打开的Tab),用户不想丢失这些状态。

android:clearTaskOnLanunch

     用法<activity android:clearTaskOnLanunch=”true/false”></activity>

     用来标记是否从Task中清除所有的Activity,除了根Activity外(每当从主画面重新启动时)——“true”,表示总是清除至它的 根 Activity,“false”表示不。默认值是“false”。这个特性只对启动一个新的Task的Activity(根Activity)有意义;对Task中其它的Activity忽略。
     当这个值为“true”,每次用户重新启动这个Task时,都会进入到它的根Activity中,不管这个Task最后在做些什么,也不管用户是使 用 BACK还是HOME离开的。当这个值为“false”时,可能会在一些情形下(参考alwaysRetainTaskState特性)清除Task的 Activity,但不总是。
     假设,某人从主画面启动了Activity P,并从那里迁移至Activity Q。接下来用户按下HOME,然后返回Activity P。一般,用户可能见到的是Activity Q,因为它是P的Task中最后工作的内容。然而,如果P设定这个特性为“true”,当用户按下HOME并使这个Task再次进入前台时,其上的所有的 Activity(在这里是Q)都将被清除。因此,当返回到这个Task时,用户只能看到P。
    如果这个特性和allowTaskReparenting都设定为“true”,那些能重新宿主的Activity会移动到共享affinity的Task中;剩下的Activity都将被抛弃,如上所述。

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值