Task和Back Stack(四)

        接着上一篇 Task和Back Stack(三)继续

        如何定义启动模式

        二、使用Intent的Flags

        试图启动一个activity时,你可以在startActivity()中为其传递的Intent设置Flags值,以此修改目标activity与task的关联方式。可选值如下:
        FLAG_ACTIVITY_NEW_TASK
        在新的task中启动该activity。如果该activity的一个task正在后台运行,则此task会被带到前台运行,其进入后台前的最终状态会被恢复,这个activity会通过其onNewIntent()方法接收新的Intent。
        这个属性产生的行为会与上一节提到的singleTask启动模式产生相同的行为。
        FLAG_ACTIVITY_SINGLE_TOP
        如果被启动的activity为当前activity(既当前back stack的栈顶activity),那么这个activity会通调用其onNewIntent()方法,而不会创建一个新的实例。
这个属性产生的行为会与上一节提到的singleTop启动模式产生相同的行为。
        FLAG_ACTIVITY_CLEAR_TOP
        如果被启动的activity正运行于当前task中,那么对应back stack内在此activity之上的所有activity都会被销毁,Intent会被这个已经处于栈顶并已恢复状态的activity接受。而不会创建新的实例。
        launchMode中没有属性值会产生与此对应的行为。

FLAG_ACTIVITY_CLEAR_TOP 通常与FLAG_ACTIVITY_NEW_TASK结合使用。当他们一起使用时,设置Flags值是一种将activity放置到task中一个能够处理Intent的位置的方式。

       (此时再回过头看看上一篇的内容,会感觉,这里FLAG_ACTIVITY_NEW_TASK的说明和FLAG_ACTIVITY_CLEAR_TOP的说明跟singleTask的实践结果相矛盾了!)


        处理affinity(亲和力)
        affinity意味着一个Activity属于哪个Task中,默认情况下,来自同一应用的所有Activity都有各自的affinity值。所以默认情况下,同一应用的所有的Activity都在同一个Task中。不过你可以修改一个Activity的默认affinity值。不同应用中定义的Activity可以共享一个affinity,同一个应用中定义的Activity也可以被分配不同的Task affinity。
        你可以通过<activity>元素的taskAffinity属性为任意给定的Activity设置affinity值。
        taskAffinity属性接受一个字符串值,这个值必须不同于<manifest>标签中默认的包名,因为系统会用这个包名来标识应用的默认task affinity。

        affinity会在两种情况下进入运行
        一、当启动这个Activity的Intent包含一个FLAG_ACTIVITY_NEW_TASK标识时。
        默认情况下,一个新的Activity会启动并进入调用startActivity()方法的Activity所在的task中,同时这个新创建的Activity实例也会被压入调用者所在的back stack中。然而,如果通过startActivity()方法传递的Intent包含一个FLAG_ACTIVITY_NEW_TASK标识,那么系统会寻找一个不同的task用来装载这个Activity。一般是创建一个新的task,不过也不一定是新的,假如已经存在一个task持有一个与这个新的Activity相同的affinity,那么这个Activity会被压入装在到那个Task中,如果不存在这样的Task,则会重新创建一个。
       假如这个标识导致一个Activity在新的task中被创建,然后用户点击Home按键离开这个Activity(这样会离开这个新建的task),那么必须有其他的方法让用户能够导航回到原来的task中。有些实体应用(如通知栏管理器),通常在可以通过外部的task来启动一个Activity,而这些新启动的Activity始终不会作为他们自己的一部分,所以会在startActivity()方法传递的Intent中设置一个Flags值为FLAG_ACTIVITY_NEW_TASK。假如你有一个Activity,这个Activity能够被外部使用了这个Flag值的实体调用,那么需要当心用户可以通过一种独立的方式回到那个已经启动的task中,比如通过一个启动图标(一个task的根Activity拥有一个ACTEGORY_LAUNCHER intent filter,参考下节 starting a task)
        二、当一个Activity的属性值allowTaskReparenting为true时
        这种情况下,当那个Task来到前台的时候,这个Activity能够从它被启动的Activity中移动到其affinity值设置的Task中。
建议:假如从用户的角度看,你的一个 .apk文件包含一个以上的application,那么你可以使用TaskAffinity属性为Activity指定不同的affinity值,让他们关联到各自的应用中。


        清除Back stack
        假如用户离开一个Task很长一段时间,系统会清除Task中除了根Activity以外的其他所有Activity。当用户在次回到这个Task中的时候,只有这个根Activity会被恢复。系统之所以这样做,是因为,在延长了很长一段时间以后,用户可能已经放弃了他们在离开该应用之前所做的行为。
        下面是可以用于修改这种行为的一些Activity的属性值
        alwaysRetainTaskState
        如果这个属性在一个Task的根Activity中被设置为true,那么上述默认的行为将不会发生。及时经过很长的一段时间,Task也会保存其所有Activity的状态。
        clearTaskOnLaunch
        如果这个属性在一个Task的根Activity中被设置为true,那么不论何时,当用户离开这个Task后再返回时,stack都会清除,根Activity。换句话说,这个属性和  alwaysRetainTaskState相反。即使只离开了一小会儿,用户也会回到这个task的初始状态。
         finishOnTaskLaunch
        这个属性和clearTaskOnLaunch相似,但其只适用于单个Activity,而不是整个task。这个属性也可以使Activity被清除,包括根Activity。当他们设置为true时,对应的Activity只会在当前的session中作为task的一部分。如果用户离开后再回到这个task中,它也不会再呈现出来。 例如:假设一个报告指定城市天气状况的Activity被申明为一个旅游应用的一部分,这个Activity的affinity具有与同一应用内的其他Activity相同的affinity(默认的affinity),并且允许设置它的allowTaskReparenting属性值为true。那么当你的其中一个Activity启动这个天气预报Activity时,他初始化的情况是和你的Activity在同一个Task中的。不过,当这个旅游应用的Task来到前台时,这个天气预报的Activity会被重新分配到旅游应用的Task中,并在其中进行展示。

        开启一个task
       你可以通过"android.intent.action.MAIN" 和"android.intent.category.LAUNCHER" 设置一个Activity,将其作为一个task的切入点,如下所示

<activity ... >
   
<intent-filter ... >
       
<action android:name="android.intent.action.MAIN" />
       
<category android:name="android.intent.category.LAUNCHER" />
   
</intent-filter>
    ...
</activity>
        第二项非常重要: 用户必须能够离开一个task并允许回到这个task通过入口Activity。基于此,singleTask和singleInstance这两种启动模式通常只在一个Activity设置了 ACTION_MAIN 和 CATEGORY_LAUNCHER 时用于标识启动一个task。想象下,如果一个filter消失了,会发生什么:一个Intent启动一个singleTask模式的Activity,这个singleTask启动一个task,用户在这个新的task中完成一些工作,然后点击Home按键。这个task被放置到后台运行,不再可见。那么现在用户将没有方法可以再回到这个task,因为他不会被呈现在应用的启动项中。
        在你不想让用户回到这个Activity的情况下,可以设置这个<activity>元素的finishOnTaskLaunch为true。

        

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值