android Intent Flags及Task相关属性

[color=blue][b]task是一个具有栈结构的容器,可以放置多个Activity实例。[/b][/color]启动一个应用,系统就会为之创建一个task,来放置根Activity;
默认情况下,一个Activity启动另一个Activity时,两个Activity是放置在同一个task中的,后者被压入前者所在的task栈,[b]当用户按下后退键,后者从task被弹出[/b],前者又显示在幕前,特别是启动其他应用中的Activity时,两个Activity对用户来说就好像是属于同一个应用;
系统task和task之间是互相独立的,当我们运行一个应用时,按下Home键回到主屏,启动另一个应用,这个过程中,之前的task被转移到后台,新的task被转移到前台,其根Activity也会显示到幕前,过了一会之后,在此按下Home键回到主屏,再选择之前的应用,之前的task会被转移到前台,[b]系统仍然保留着task内的所有Activity实例,而那个新的task会被转移到后台[/b],如果这时用户再做后退等动作,就是针对该task内部进行操作了。

[size=medium][color=red][b]task相关的知识,主要分以下几点:[/b][/color][/size]

[b][color=blue]1.Activity的affinity(亲和力)[/color][/b]

[b]2.Intent几种常见的flags[/b]

[color=red]3.<activity>与task相关属性[/color]

[size=medium][color=red][b]affinity:[/b][/color][/size]

[b]拥有相同affinity的多个Activity理论同属于一个task,task自身的affinity决定于根Activity的affinity值。[/b]

[size=medium][color=red][b]affinity在什么场合应用呢?[/b][/color][/size]

1.根据affinity重新为Activity选择宿主task(与allowTaskReparenting属性配合工作);

[b]2.启动一个Activity过程中Intent使用了FLAG_ACTIVITY_NEW_TASK标记,根据affinity查找或创建一个新的具有对应affinity的task。[/b]

默认情况下,[size=medium][color=blue][b]一个应用内的所有Activity都具有相同的affinity[/b][/color][/size],都是从Application(参考<application>的taskAffinity属性)继承而来,而Application默认的affinity是<manifest>中的包名,我们可以为<application>设置taskAffinity属性值,这样可以应用到<application>下的所有<activity>,也可以单独为某个Activity设置taskAffinity。
例如:在系统自带的Browser中,package为com.android.browser,但是<application>却自定义一个taskAffinity属性值:


<application android:name="Browser"
android:label="@string/application_name"
android:icon="@drawable/ic_launcher_browser"
android:backupAgent=".BrowserBackupAgent"
android:taskAffinity="android.task.browser" >


[size=medium][color=blue][b]Intent几种常见的flags:[/b][/color][/size]

在android.content.Intent中定义了若干个flags,其中最重要的有以下几个:

[size=medium][color=red][b]1.FLAG_ACTIVITY_NEW_TASK:[/b][/color][/size]

当Intent对象包含这个标记时,[b]系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。[/b]注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。下面我们会通过实例进行演示这个特性:

我们新建两个项目,分别命名为appA和appB,并且分别创建FirstActivity和SecondActivity,我们准备让appB中的FirstActivity跳转到appA的SecondActivity。appA中的SecondActivity配置如下:


<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="android.intent.action.APP_A_SECOND_ACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>


FLAG_ACTIVITY_NEW_TASK应该这样去理解:[color=red][b]根据Activity Affinity判断是否需要创建新的Task,然后再创建新的Activit实例放进去。[/b][/color]

[size=medium][color=red][b]2.FLAG_ACTIVITY_CLEAR_TOP:[/b][/color][/size]

[color=blue][b]当Intent对象包含这个标记时,如果在栈中发现存在Activity实例,则清空这个实例之上的Activity,使其处于栈顶。[/b][/color]
例如:我们的FirstActivity跳转到SecondActivity,SecondActivity跳转到ThirdActivity,而ThirdActivity又跳到SecondActivity,那么ThirdActivity实例将被弹出栈,使SecondActivity处于栈顶,显示到幕前,栈内只剩下FirstActivity和SecondActivity。
这个SecondActivity既可以在onNewIntent()中接收到传来的Intent,也可以把自己销毁之后重新启动来接受这个Intent。在使用默认的“standard”启动模式下,如果没有在Intent使用到FLAG_ACTIVITY_SINGLE_TOP标记,那么它将关闭后重建,如果使用了这个FLAG_ACTIVITY_SINGLE_TOP标记,则会使用已存在的实例;
对于其他启动模式,无需再使用FLAG_ACTIVITY_SINGLE_TOP,它都将使用已存在的实例,Intent会被传递到这个实例的onNewIntent()中。

简单点理解:[b]FLAG_ACTIVITY_CLEAR_TOP表示启动的Activity会将Task中位于其上的Activity都强制出栈,使其自身位于栈顶。[/b]在Standard模式下,如果原来的Activity栈顺序为 A -> B1 -> D, 此时D通过FLAG_ACTIVITY_CLEAR_TOP启动B,则栈顺序为A -> B2。对于同时设置了FLAG_ACTIVITY_SINGLE_TOP,则栈顺序为 A-> B1(此时回调onNewIntent()..),此时效果与Activity启动模式中的singleTask相同。

[size=medium][color=red][b]3.FLAG_ACTIVITY_SINGLE_TOP:[/b][/color][/size]

当task中存在目标Activity实例并且位于栈的顶端时,不再创建一个新的,直接利用这个实例。我们在上边的例子中也有讲到。

目前发现与Activity启动模式中的singleTop效果相同。

[size=medium][color=red][b]4.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:[/b][/color][/size]

如果一个Intent中包含此属性,则它转向的那个Activity以及在那个Activity其上的所有Activity都会在task重置时被清除出task(前提:FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)。当我们将一个后台的task重新回到前台时,系统会在特定情况下为这个动作附带一个FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,意味着必要时重置task,这时FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET就会生效。经过测试发现,对于一个处于后台的应用,如果在主选单点击应用,这个动作中含有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,长按Home键,然后点击最近记录,这个动作不含FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记,所以前者会清除,后者不会。

[size=medium][color=red][b]5.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:[/b][/color][/size]

这个标记在以下情况下会生效:[b]1.启动Activity时创建新的task来放置Activity实例;2.已存在的task被放置于前台。[/b]
系统会根据affinity对指定的task进行重置操作,task会压入某些Activity实例或移除某些Activity实例。我们结合上面的CLEAR_WHEN_TASK_RESET可以加深理解。


转自:[url]http://www.cnblogs.com/lwbqqyumidi/p/3775479.html[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值