Activity跳转Flag详解

来源:互联网 发布:企业成本核算软件 编辑:程序博客网 时间:2024/05/21 08:58

下面是关于setFlags的一下属性的解释:

一、Activity和Task(栈)的关系
Task就像一个容器,而Activity就相当与填充这个容器的东西,第一个东西(Activity)则会处于最下面,最后添加的东西(Activity)则会在最低端。从Task中取出东西(Activity)则是从最顶端取出,也就是说最先取出的是最后添加的东西(Activity),一次类推,最后取出的是第一次添加的Activity,而Activity在Task中的顺序是可以控制的,那则在Activity跳转时用到Intent Flag
二、界面跳转和服务的启动都会用到Intent,现在介绍IntentFlag是关于Activity的跳转
Intent intent = new Intent(this,xxx.class);
//如果activity在task存在,拿到最顶端,不会启动新的Activity
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
//如果activity在task存在,将Activity之上的所有Activity结束掉
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//默认的跳转类型,将Activity放到一个新的Task中
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//如果Activity已经运行到了Task,再次跳转不会在运行这个Activity
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

 

Android 的一个特色就是application A的 activity 可以启动application B 的 activity,尽管 A 和 B 是毫无干系的,而在用户看来,两个场景紧密联系,视觉上二者构成了一个整体。Android就是把这种误觉定义为 Task,它既不是 class,也不是 AndroidMainifest.xml 中的一个元素。从表现上看 Task 就像是一个 stack,一个一个的 activity 是构成 stack 的元素,做着入栈 (push) 和出栈 (pop-up)这样简单重复性的劳动。

默认的规则总是满足大多数的应用场景,但是也总会有一些例外打破习以为常的惯例。Task 的默认规则同样并非牢不可破,修改的方法还是有的。借助 Intent 中的 flag 和AndroidMainifest.xml 中 activity 元素的属性,就可以控制到 Task 里 Activity 的关联关系和行为。

在 android.content.Intent 中一共定义了20种不同的 flag,其中和 Task 紧密关联的有四种:
1.FLAG_ACTIVITY_NEW_TASK
2.FLAG_ACTIVITY_CLEAR_TOP
3.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
4.FLAG_ACTIVITY_SINGLE_TOP

在使用这四个 flag 时,一个 Intent 可以设置一个 flag,也可以选择若干个进行组合。

默认情况下,通过 startActivity() 启动一个新的Activity,新的 Activity 将会和调用者在同一个stack 中。但是,如果在传递给 startActivity() 的 Intent 对象里包含了 FLAG_ACTION_NEW_TASK,情况将发生变化,–系统将为新的 Activity “寻找”一个不同于调用者的 Task。不过要找的 Task 是不是一定就是 NEW 呢?如果是第一次执行,则这个设想成立,如果说不是,也就是说已经有一个包含此Activity 的Task 存在,则不会再启动Activity。

如果 flag 是FLAG_ACTIVITY_CLEAR_TOP,同时当前的 Task 里已经有了这个 Activity,那么情形又将不一样。Android 不但不会启动新的 Activity 实例,而且还会将 Task 里 该 Activity 之上的所有 Activity 一律结束掉,然后将 Intent 发给这个已存在的 Activity。Activity 收到 Intent 之后,可以在 onNewIntent() 里做下一步的处理,也可以自行结束然后重新创建自己。如果Activity 在 AndroidMainifest.xml 里将启动模式设置成”multiple”,– 默认模式,并且Intent 里也没有设置 FLAG_ACTIVITY_SINGLE_TOP,那么它将选择后者。否则,它将选择前者。FLAG_ACTIVITY_CLEAR_TOP 还可以和FLAG_ACTION_NEW_TASK 配合使用。

如果 flag 设置的是FLAG_ACTIVITY_SINGLE_TOP,则意味着如果 Activity 已经是运行在 Task 的 top,则该Activity 将不会再被启动。

 


设置intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

 

 

Intent.FLAG_ACTIVITY_NEW_TASK

默认的跳转类型,会重新创建一个新的Activity,不过与这种情况,比方说栈中有A,B,C三个Activity,此时在C中启动D的话,如果在Manifest.xml文件中给D添加了Affinity的值和Task中的不一样的话,则会在新标记的Affinity所存在的Task中压入这个Activity。如果是默认的或者指定的Affinity和Task一样的话,就和标准模式一样了启动一个新的Activity.

FLAG_ACTIVITY_NO_HISTORY

意思就是说用这个FLAG启动的Activity,一旦推出,他就不会存在于栈中,原来是A,B,C 这个时候再C中以这个FLAG启动D的 , D再启动E,这个时候栈中情况为A,B,C,E。

FLAG_ACTIVITY_BROUGHT_TO_FRONT

这个意思是重新创建一个新的Activity(即便堆栈中已经存在这个Activity),并提到栈顶。

比如,A,B,C,D都是标准加载,然后我在D中启动A,这个intent加上FLAG_ACTIVITY_BROUGHT_TO_FRONT ,不要会误认为变成B,C,D,A!!其实不是,这个时候应该是A,B,C,D,A.不信的人大家试试看。不过下面这个标记和这个标记就会让大家明白了!

FLAG_ACTIVITY_REORDER_TO_FRONT区别

这个的意思是如果栈里已经存在,则将它拿到栈顶,不会启动新Activity。比如栈中有A,B,C三个Activity。此时在C中启动A的话,这时候栈的顺序为B,C,A。

 

参考:

Intent对象在Android开发中起着举足轻重的作用,其内置了丰富的常量,用于传递数据,下面本文将介绍跟Task有关的一些Flag参数,各参数的理解均来自Android API和本人在实际项目中的体验,如果有描述不当之处,还请各位不吝赐教。

 

FLAG_ACTIVITY_BROUGHT_TO_FRONT: 这个标志一般不是由程序代码设置的,如在launchMode中设置singleTask模式时系统帮你设定。

 

FLAG_ACTIVITY_CLEAR_TOP: 如果目标Activity已经运行于当前的Task中,则关闭Activity Stack中在此Activity上方的所有Activity,然后将此Intent传递到该Activity实例内。例如,假设一个Task的Activity Stack中包含这些Activity:A,B,C,D。如果D调用了startActivity(),并且Intent指向B,那么,C和D都将结束,然后B接收到这个Intent,因此,目前stack的状况是:A,B。

 

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET: 如果设置,这将在Task的Activity Stack中设置一个还原点,当Task恢复时,需要清理Activity。例如下一次Task带着FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记进入前台时,这个Activity和它之上的都将关闭,以至于用户不能再返回到它们,但是可以回到之前的Activity。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS: 如果设置,新的Activity不会在最近启动的Activity的列表中保存。

 

FLAG_ACTIVITY_FORWARD_RESULT: 如果设置,并且这个Intent用于从一个存在的Activity启动一个新的Activity,那么,这个作为答复目标的Activity将会传到这个新的Activity中。这种方式下,新的Activity可以调用setResult(int),并且这个结果值将发送给那个作为答复目标的Activity。

 

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY: 这个标志一般不由应用程序代码设置,如果这个Activity是从历史记录里启动的(常按HOME键),那么,系统会帮你设定。

 

FLAG_ACTIVITY_MULTIPLE_TASK: 不建议使用此标志,除非你自己实现了应用程序启动器。

 

FLAG_ACTIVITY_NEW_TASK: 将使Activity成为一个新Task的开始。

 

FLAG_ACTIVITY_NO_ANIMATION:  这个标志将阻止系统进入下一个Activity时应用Acitivity迁移动画。

 

FLAG_ACTIVITY_NO_HISTORY: 新的Activity将不再历史stack中保留。一旦离开,此Activity就关闭了。

 

FLAG_ACTIVITY_NO_USER_ACTION: 这个标志将在Activity暂停之前阻止从最前方的Activity回调的onUserLeaveHint()。

 

FLAG_ACTIVITY_PREVIOUS_IS_TOP: If set andthis intent is being used to launch a new activity from an existing one, thecurrent activity will not be counted as the top activity for deciding whetherthe new intent should be delivered to the top instead of starting a new one.The previous activity will be used as the top, with the assumption being thatthe current activity will finish itself immediately.

 

FLAG_ACTIVITY_REORDER_TO_FRONT: 这个标志将引发已经运行的Activity移动到历史stack的顶端。

 

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED: Ifset, and this activity is either being started in a new task or bringing to thetop an existing task, then it will be launched as the front door of the task.This will result in the application of any affinities needed to have that taskin the proper state (either moving activities to or from it), or simplyresetting that task to its initial state if needed.

 

FLAG_ACTIVITY_SINGLE_TOP:  如果Activity位于Activity Stack的顶端,则不再创建一个新的实例。

 

  上面纷杂的Intent内置参数在简单的Android应用时,可以启到比较好的控制作用,但是一旦Android应用过于复杂,那么自定一个Activity List以管理Activity不失于一种更好更高效的管理方法。

 

0 0