您的位置:首页 > 移动开发 > Android开发

Android Intent的FLAG标志和activty 启动模式

2018-01-30 11:59 183 查看
之前在做项目的时候遇到有关 activty 启动模式 和 Intent的FLAG标志 的问题,纠结了很久,在网上看了很多有关的文章,很多都写的很复杂,感觉不适合我这种急着解决问题的菜鸟,所以今天就把它简洁的记录一下,方便和我一样急着解决问题的菜鸟参考。

Activity的四种启动模式:

standard

singleTop

singleTask

singleInstance

属性说明:

1. standard:

每次启动都会创建一个新的activity(这种启动模式是activity默认的启动模式,会重复创建);

2.singleTop:

在顶部只能有一个(如果当前activity就是栈顶显示的activity,那么你再去启动它的时候不会重复创建,而是复用你启动前的activity,当然如果不属于栈顶的之前已经启动过的activity,你再去启动的话,就会重复创建了);

3.singleTask:

只允许存在一个实例(如果系统中已经存在了该种启动模式的目标Activity,则系统并不会重新创建一个目标Activity,而是首先将持有目标Activity的整个任务栈都会被置于前台)

4.singleInstance:

只允许存在一个目标Activity(这种启动模式和singleTask几乎一样,它也只允

许系统中存在一个目标Activity,包括SingleTask的一些特性singleInstance

都有。唯一不同的是,持有目标Activity的任务栈中只能有目标Activity一

个Actvitiy,不能再有别的Activity)

设置方式:

在 AndroidMenifest.xml 文件中的 标签中设置android:launchMode=”singleInstance” 即可。

例:

<activity
android:name=".activity.TextActivity"
android:launchMode="singleTask"/>


Android Intent的FLAG 值

除在配置文件里面可以设置 activity启动模式 之外,在启动 activity 的时候也可以在 InIntent 中通过addFlags 设置。

Intent的FLAG 值:

1. FLAG_ACTIVITY_BROUGHT_TO_FRONT:

这个Flag的意思,比如我现在有一个A,然后在A中启动B,并设置

FLAG_ACTIVITY_BROUGHT_TO_FRONT这个启动标记,那么B就是

以FLAG_ACTIVITY_BROUGHT_TO_FRONT启动的。然后在B中启动C,此时栈就是A,B,C。如果这个时候在C中启动B,那么栈的情况会是A,C,B。

2.FLAG_ACTIVITY_REORDER_TO_FRONT:

如果在栈中有A,B,C三个Activity,并且是正常启动的,此时在C中启动B的话,还是会变成A,C,B的。 如果使用了标志FLAG_ACTIVITY_CLEAR_TOP,那这个

FLAG_ACTIVITY_REORDER_TO_FRONT标志会被忽略。

3.FLAG_ACTIVITY_NEW_TASK:

假设现在有一个栈1,里面是A,B,C。此时,在C中启动D的时候,设置

FLAG_ACTIVITY_NEW_TASK标记,此时会有两种情况:

1.如果D这个Activity在Manifest.xml中的声明中添加了Task Affinity,系统首先会查找有没有和D的Task Affinity相同的Task栈存在,如果有存在,将D压入那个栈

2.如果D这个Activity在Manifest.xml中的Task Affinity默认没有设置,则会把其压入栈1,变成:A B C D,这样就和标准模式效果是一样的了。

也就是说,设置了这个标志后,新启动的Activity并非就一定在新的Task中创建,如果A和B在属于同一个package,而且都是使用默认的Task Affinity,那B还是会在A的task中被创建。 所以,只有A和B的Task Affinity不同时,设置了这个标志才会使B被创建到新的Task。注意如果试图从非Activity的非正常途径启动一个Activity,比如从一个Receiver中启动一个Activity,则Intent必须要添加FLAG_ACTIVITY_NEW_TASK标记。

4.FLAG_ACTIVITY_CLEAR_TASK:

如果Intent中设置了这个标志,会导致含有待启动Activity的Task在Activity被启动前清空。也就是说,这个Activity会成为一个新的root,并且所有旧的activity都被finish掉。这个标志只能与FLAG_ACTIVITY_NEW_TASK 一起使用。

5.FLAG_ACTIVITY_SINGLE_TOP:

这个FLAG就相当于加载模式中的singleTop,比如说原来栈中情况是A,B,C,D在D中启动D,栈中的情况还是A,B,C,D。

6.FLAG_ACTIVITY_CLEAR_TOP:

这个FLAG就相当于加载模式中的SingleTask,如果启动的Activity存在当前的栈中,系统会把要启动的Activity之上的Activity全部弹出栈空间,然后把Intent作为一个新的Intent传给这个Activity。

例如:原来栈中的情况是A,B,C,D这个时候从D中跳转到B,这个时候栈中的情况就是A,B了。上面例子中运行的B activity既可以在onNewIntent()中接收新的Intent,也可以将自己finish掉然后使用新的Intent重启。如果在它的launch mode中设置了”multiple”(默认),并且intent中没有设置FLAG_ACTIVITY_SINGLE_TOP 标志,那它就会被finish掉然后重新创建。如果是其它的launchMode或者是设置了FLAG_ACTIVITY_SINGLE_TOP 属性,那就会使用现有的实例的OnNewIntent()方法来接受Intent。

这种启动模式也可以与 FLAG_ACTIVITY_NEW_TASK 一起使用:如果用来启动一

个任务的root activity,它会将这个任务中现在运行的实例调到前台,然后将

任务清空至只有根Activity的状态。这很有用,例如要从通知中心里启动一

个Activity时。

7.FLAG_ACTIVITY_NO_HISTORY:

用这个FLAG启动的Activity,一但退出,就不会存在于栈中。栈中是A,B,C 这个时候再C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。简而言之,跳转到的activity不压在栈中。

8.FLAG_ACTIVITY_NO_USER_ACTION:

如果设置了这个标志,可以在避免用户离开当前Activity时回调到onUserLeaveHint()。通常,Activity可以通过这个回调表明有明确的用户行为将当前Activity切出前台。这个回调标记了Activity生命周期中的一个恰当的点

,可以用来“在用户看过通知之后”将它们清除,如闪烁LED灯。

如果Activity是由非用户驱动的事件(如电话呼入或闹钟响铃)启动的,那这个标志就应该被传入Context.startActivity,以确保被打断的Activity不会认为用户已经看过了通知。

9.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:

设置这个标志意味着在activity栈中做一个标记,在Task重置的时候栈就把从标记往上的activity都清除。也就是说,下次这个Task被通过

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED调到前台时(通常是由于用户从桌面重新启动),这个activity和它之上的activity都会被finish掉,这样用户就不会再回到他们,而是直接回到在它们之前的activity。

10.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:

如果设置这个标志,这个Activity就不会在近期任务中显示。

11.FLAG_ACTIVITY_FORWARD_RESULT:

如果Activity A 在启动 Activity B时设置了这个标志,那A的答复目标目标会传递给B,这样一来B就可以通过调用setResult(int) 将返回结果返回给A的答复目标。

12.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY:

这个标志通常情况下不会通过应用的代码来设置,而是在通过最近任务启动activity时由系统设置的。

13.FLAG_ACTIVITY_NO_ANIMATION:

禁用掉系统默认的Activity切换动画。

14.FLAG_ACTIVITY_TASK_ON_HOME:

这个标志可以将一个新启动的任务置于当前的home任务(home activity task)之上(如果有的话)。也就是说,在任务中按back键总是会回到home界面,而不是回到他们之前看到的activity。这个标志只能与FLAG_ACTIVITY_NEW_TASK标志一起用。

比如,A->B->C->D,如果在C启动D的时候设置了这个标志,那在D中按Back键则

是直接回到桌面,而不是C。

注意:只有D是在新的task中被创建时(也就是D的launchMode是singleInstance时,或者是给D指定了与C不同的taskAffinity并且加了FLAG_ACTIVITY_NEW_TASK标志时),使用 FLAG_ACTIVITY_TASK_ON_HOME标志才会生效。感觉实际使用效果和用 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK 的效果一样。

15.FLAG_FROM_BACKGROUND:

可以给调用者用来标识这个Intent是来自后台操作,而不是用户的交互行为。

Android Intent FLAG 的设置方式:

Intent intentfin = new Intent(this, MainActivity.class);
intentfin.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intentfin);


以上内容是纯属个人和参考大神文章的一些理解,主要是为了方便查看而整理一下,不足之处请大神指正。

附上参考的文章链接:

Activity的4种启动模式

Android Intent的FLAG标志详解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息