Android任务和返回栈Mark

参考:http://blog.csdn.net/guolin_blog/article/details/41087993

任务和返回栈的概念

任务是activity的集合,它使用栈的方式管理其中的activity,这个栈就是返回栈,activity在栈中的顺序是按照activity打开的顺序存放的

activity调用那些事

1、同一个任务中的activity可以相互调用。同一任务中当前正在运行的activity总是在栈顶,在standard启动模式(启动模式在后面讲到)下,当同一任务中的activity(设为A)启动了另一个activity(设为B)时,B会被创建并且放到栈顶,而A自然就在B的下面并且处于停止状态,当用户按下返回键,B被弹出,A重新回到栈顶

2、一个任务的activity可以启动另一个任务的activity。有关启动其他任务的activity返回栈的变动,放在启动模式来讨论。

任务的后台和前台:当用户在Home界面上点击了一个应用的图标时,这个应用的任务就会被转移到前台。如果这个应用目前并没有一个已经存在的任务的话(说明这个应用最近没有被启动过),系统就会去创建一个新的任务,并且将该应用的主Activity放入到返回栈当中。任务除了可以被转移到前台之外,当然也是可以被转移到后台的。当用户开启了一个新的任务,或者点击Home键回到主屏幕的时候,之前任务就会被转移到后台了。当任务处于后台状态的时候,返回栈中所有的Activity都会进入停止状态,但这些Activity在栈中的顺序都会原封不动地保留着

管理任务

两种方式:(1)mainfest文件中设置activity的属性;(2)启动activity的时候配置intent的flag
activity有以下属性可以用:

  • taskAffinity
  • launchMode
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch

intent的flag有以下比较常用:
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_CLEAR_TOP
- FLAG_ACTIVITY_SINGLE_TOP

1、设置activity属性的方式

(1)设置launchmode:

standard
standard默认的启动方式,如果不指定Android就会使用这种启动方式,在这种启动方式下,当前被启动的activity总是会被实例化,并且总是放在当前的任务栈中,声明这种启动模式的activity一把会被实例化多次,一个任务栈可能会含有多个这样的实例
singleTop
如果当前返回栈的栈顶是我们现在要启动的activity,系统不会重新实例化这个activity实例,而是会调用这个activity的onNewIntent()方法。声明这种启动模式的activity可以被启动多次,一个任务当中也可以包含多个这个activity的实例
singleTask
如果一个任务中的activity(设为A)要启动另一个任务中的activity(设为B),B启动模式设置为singleTask,系统会创建一个新的任务,并且把B放到新任务的栈底位置。如果原来的任务中已经有B的实例,系统不会再创建一次B,而是调用它的onNewIntent()方法。但是如果B是属于A所在的任务,B即使设置为了singleTask启动模式,系统也不会为它创建一个新任务(后面affinity时候解释)。
singleInstance
与singleTask唯一不同的点就是被启动的activity(B)如果设置为这种模式,除了要新建一个任务外,在该任务里面还不允许方其他activity,也就是说设置为这种启动模式的activity的任务栈只能有一个activity。

注:不管activity是在当前任务中启动还是在新任务中启动, 返回键永远都会把我们带到前一个activity,但是有一点比较特殊:如果activity被设置为singleTask,并且这个activity正好处于一个后台任务当中,就会直接将这整个后台任务直接切换到前台,这时如果按返回键就会将目前这个前台任务回退,完再回到启动activity(B)的A,示意图如下:
这里写图片描述

(2)设置taskAffinity
affinity可以用于指定一个activity更加依附于哪一个任务,默认情况下一个任务中的所有activity的affinity值相同(一般默认是应用包名)
affinity一般的值是一个字符串,如果自己指定,建议不要用应用程序包名(默认就是应用程序包名)

affinity应用场景(建议看了下面的Intent的flag再看这里):

  • 当用startActivity()启动一个activity时候,如果这个activity的flag设置为FLAG_ACTIVITY_NEW_TASK 或这启动模式设置为singleTask,系统会先检查这个activity的affinity值和当前任务的affinity值是否相同,如果相同仍然把这个activity放到当前任务中,如果不同就新建一个任务。默认情况一个任务中的所有activity的affinity都是相同的,所以就解释了前面singleTask为什么同一个任务中的activity相互调用即使设置了singleTask仍然不会创建一个新的任务。另外你也可以通过制定另外一个任务中的activity的affinity值和你当前任务的activity的affinity值一样让这个activity仍然放到当前任务中。

  • 与 allowTaskReparenting 属性结合使用:当把Activity的allowTaskReparenting属性设置成true时,Activity就拥有了一个转移所在任务的能力。具体点来说,就是一个Activity现在是处于某个任务当中的,但是它与另外一个任务具有相同的affinity值,那么当另外这个任务切换到前台的时候,该Activity就可以转移到现在的这个任务当中。
    那还是举一个形象点的例子吧,比如有一个天气预报程序,它有一个Activity是专门用于显示天气信息的,这个Activity和该天气预报程序的所有其它Activity具体相同的affinity值,并且还将allowTaskReparenting属性设置成true了。这个时候,你自己的应用程序通过Intent去启动了这个用于显示天气信息的Activity,那么此时这个Activity应该是和你的应用程序是在同一个任务当中的。但是当把天气预报程序切换到前台的时候,这个Activity又会被转移到天气预报程序的任务当中,并显示出来,因为它们拥有相同的affinity值,并且将allowTaskReparenting属性设置成了true。

(3)设置clearTaskOnLaunch、alwaysRetainTaskState、finishOnTaskLaunch
如何用户将任务切换到后台之后过了很长一段时间,系统会将这个任务中除了最底层的那个Activity之外的其它所有Activity全部清除掉。当用户重新回到这个任务的时候,最底层的那个Activity将得到恢复。这个是系统默认的行为,因为既然过了这么长的一段时间,用户很有可能早就忘记了当时正在做什么,那么重新回到这个任务的时候,基本上应该是要去做点新的事情了。
当然,既然说是默认的行为,那就说明我们肯定是有办法来改变的,在元素中设置以下几种属性就可以改变系统这一默认行为:

alwaysRetainTaskState
如果将最底层的那个Activity的这个属性设置为true,那么上面所描述的默认行为就将不会发生,任务中所有的Activity即使过了很长一段时间之后仍然会被继续保留。
clearTaskOnLaunch
如果将最底层的那个Activity的这个属性设置为true,那么只要用户离开了当前任务,再次返回的时候就会将最底层Activity之上的所有其它Activity全部清除掉。简单来讲,就是一种和alwaysRetainTaskState完全相反的工作模式,它保证每次返回任务的时候都会是一种初始化状态,即使用户仅仅离开了很短的一段时间。
finishOnTaskLaunch
这个属性和clearTaskOnLaunch是比较类似的,不过它不是作用于整个任务上的,而是作用于单个Activity上。如果某个Activity将这个属性设置成true,那么用户一旦离开了当前任务,再次返回时这个Activity就会被清除掉。

2、配置intent的flag方式

FLAG_ACTIVITY_NEW_TASK
这个 和singleTask类似,但是还是有区别的,区别是什么还在探究
FLAG_ACTIVITY_SINGLE_TOP
设置了这个flag,如果要启动的Activity在当前任务中已经存在了,并且还处于栈顶的位置,那么就不会再次创建这个Activity的实例,而是直接调用它的onNewIntent()方法。这种flag和在launchMode中指定”singleTop”模式所实现的效果是一样的。
FLAG_ACTIVITY_CLEAR_TOP
设置了这个flag,如果要启动的Activity在当前任务中已经存在了,就不会再次创建这个Activity的实例,而是会把这个Activity之上的所有Activity全部关闭掉。比如说,一个任务当中有A、B、C、D四个Activity,然后D调用了startActivity()方法来启动B,并将flag指定成FLAG_ACTIVITY_CLEAR_TOP,那么此时C和D就会被关闭掉,现在返回栈中就只剩下A和B了。
那么此时Activity B会接收到这个启动它的Intent,你可以决定是让Activity B调用onNewIntent()方法(不会创建新的实例),还是将Activity B销毁掉并重新创建实例。如果Activity B没有在manifest中指定任何启动模式(也就是”standard”模式),并且Intent中也没有加入一个FLAG_ACTIVITY_SINGLE_TOP flag,那么此时Activity B就会销毁掉,然后重新创建实例。而如果Activity B在manifest中指定了任何一种启动模式,或者是在Intent中加入了一个FLAG_ACTIVITY_SINGLE_TOP flag,那么就会调用Activity B的onNewIntent()方法。
FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_NEW_TASK结合在一起使用也会有比较好的效果,比如可以将一个后台运行的任务切换到前台,并把目标Activity之上的其它Activity全部关闭掉。这个功能在某些情况下非常有用,比如说从通知栏启动Activity的时候。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值