Android开发——Intent中的各种FLAG

时间:2021-03-25 15:34:47


Android中发送Intent的时候有很多的标志位可以使用。是在做各种各样UI跳转时,熟悉这些标志的作用会给开发过程带来很大的遍历,这几天找时间把这些Flag都看了一遍,顺便翻译了一下,为便于理解,在翻译的时候也加了一些说明性的东西,供自己以后参考用,顺便分享出来与大家一起学习讨论。

可能有些地方会有错误,欢迎大家指正,讨论。

原创翻译,如需转载,请标明出处。

http://blog.csdn.net/javensun/article/details/8700265

其中有几处地方还是存疑状态,有问号和红色标明,这几天有空搞搞清楚。

FLAG_ACTIVITY_BROUGHT_TO_FRONT 默认标志

This flag is not normally set by application code, but set for you by the system as described in the launchMode documentation for the singleTask mode.

通常在应用代码中不需要设置这个FLAG,当launchMode为singleTask时系统会默认设置这个标志。

FLAG_ACTIVITY_CLEAR_TASK 清空任务标志

If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started. That is, the activity becomes the new root of an otherwise empty task, and any old activities are finished. This can only be used in conjunction with FLAG_ACTIVITY_NEW_TASK.

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

FLAG_ACTIVITY_CLEAR_TOP 清空任务中在其之上的Activity

If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.

For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B.

The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to the current instance's onNewIntent().

This launch mode can also be used to good effect in conjunction with FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task, it will bring any currently running instance of that task to the foreground, and then clear it to its root state. This is especially useful, for example, when launching an activity from the notification manager.

See Tasks and Back Stack for more information about tasks.

如果设置了这个标志,并且待启动的Activity已经存在于当前的task中,那就不会再给这个activity新起一个实例,而是将task中在它之上的其它activity全部关闭,然后把Intent作为一个新的Intent传给这个Activity(当前已在栈顶)。

例如,一个task中存在A,B,C,D四个Activity。如果D调用startActivity() 启动B,那么C和D会被finish掉并且B收到这个Intent,最后栈中只有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时。

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 任务重置时将任务中在此标记之后的Activity清空

If set, this marks a point in the task's activity stack that should be cleared when the task is reset. That is, the next time the task is brought to the foreground with FLAG_ACTIVITY_RESET_TASK_IF_NEEDED (typically as a result of the user re-launching it from home), this activity and all on top of it will be finished so that the user does not return to them, but instead returns to whatever activity preceeded it.

This is useful for cases where you have a logical break in your application. For example, an e-mail application may have a command to view an attachment, which launches an image view activity to display it. This activity should be part of the e-mail application's task, since it is a part of the task the user is involved in. However, if the user leaves that task, and later selects the e-mail app from home, we may like them to return to the conversation they were viewing, not the picture attachment, since that is confusing. By setting this flag when launching the image viewer, that viewer and any activities it starts will be removed the next time the user returns to mail.

设置这个标志意味着在activity栈中做一个标记,在Task重置的时候栈就把从标记往上的activity都清除。也就是说,下次这个Task被通过FLAG_ACTIVITY_RESET_TASK_IF_NEEDED调到前台时(通常是由于用户从桌面重新启动),这个activity和它之上的activity都会被finish掉,这样用户就不会再回到他们,而是直接回到在它们之前的activity。

这在应用切换时非常有用。比如,Email应用会需要查看附件,就要调用查看图片的Activity来显示,那这个查看图片的Activity就会成为Email应用任务里的一部分。但是,如果用户离开了Email的任务,过了一会儿由通过Home来选择Email应用,我们会希望它回到查看邮件会话的页面,而不是浏览图片附件的页面,不然就感觉太诡异了。如果在启动查看图片Activity时设置了这个标志,那这个Activity及由它启动的Activity在下一次用户返回邮件时都会被清除。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 不显示在近期任务中

If set, the new activity is not kept in the list of recently launched activities.

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

FLAG_ACTIVITY_FORWARD_RESULT 转发结果

If set and this intent is being used to launch a new activity from an existing one, then the reply target of the existing activity will be transfered to the new activity. This way the new activity can call setResult(int) and have that result sent back to the reply target of the original activity.

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

简单如下:

O ----startActivityForResult()----> A ----FLAG_ACTIVITY_FORWARD_RESULT----> B

A的答复目标是O,如果A在启动B时使用了这个标志,A就会把答复目标O的信息传递给B,以便B将O作为它的答复目标。此时B调用setResult()时的结果信息都会传递给O,而不会给A。并且此时在A中调用setResult()的内容不会生效。我还没发现使A中setResult()生效的方法。

注意:这个标志不能与startActivityForResult()一起使用。

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY 从近期任务中启动的标志

This flag is not normally set by application code, but set for you by the system if this activity is being launched from history (longpress home key).

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

FLAG_ACTIVITY_MULTIPLE_TASK Activity可在多任务运行的标志

Do not use this flag unless you are implementing your own top-level application launcher. Used in conjunction with FLAG_ACTIVITY_NEW_TASK to disable the behavior of bringing an existing task to the foreground. When set, a new task is always started to host the Activity for the Intent, regardless of whether there is already an existing task running the same thing.

Because the default system does not include graphical task management, you should not use this flag unless you provide some way for a user to return back to the tasks you have launched.

This flag is ignored if FLAG_ACTIVITY_NEW_TASK is not set.

See Tasks and Back Stack for more information about tasks.

除非你实现了自己的*应用启动器,否则不要使用这个标志。与 FLAG_ACTIVITY_NEW_TASK 一起使用可以不再把已存在的任务唤起到前台。 当被设置时,系统总会为Intent的Activity启动一个新的task,而不管是否已经有已存在的任务在做同样的事情。

因为默认系统不包含图形化的任务管理功能,所以除非你给用户提供了返回到已启动任务的方法,否则就不要用这个标志。

如果FLAG_ACTIVITY_NEW_TASK没有设置,则这个标志也被忽略。

FLAG_ACTIVITY_NEW_TASK 尝试在新任务中启动Activity的标志(并不一定就会在新的任务中)

If set, this activity will become the start of a new task on this history stack. A task (from the activity that started it to the next task activity) defines an atomic group of activities that the user can move to. Tasks can be moved to the foreground and background; all of the activities inside of a particular task always remain in the same order. See Tasks and Back Stack for more information about tasks.

This flag is generally used by activities that want to present a "launcher" style behavior: they give the user a list of separate things that can be done, which otherwise run completely independently of the activity launching them.

When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in. See FLAG_ACTIVITY_MULTIPLE_TASK for a flag to disable this behavior.

This flag can not be used when the caller is requesting a result from the activity being launched.

设置这个标志可以为待启动的Activity创建一个新的任务。一个任务(从启动它的Activity到任务中的下一个Activity)就是用户可以跳转到的Activity的原子群。任务可以在前台与后台之间切换;在某一特定任务之中的所有Activity一直会保持同样的顺序。

这个标志通常被用来呈现一种"laucher"类型的行为:为用户提供一个可单独解决的事情列表,完全独立于启动他们的Activity之外运行。

使用这个标志时,如果有一个任务已经运行了你要启动的Activity,那就不会在创建新的Activity,而是将现有的任务保持之前的状态直接唤到前台。参见FLAG_ACTIVITY_MULTIPLE_TASK这个标志,可以禁用掉这个行为。

这个标志不能在调用者向待启动Activity请求返回结果时使用。

注意:假设A启动B,如果要让B在新的task中创建,要求这两个Activity的taskAffinity不同。也就是说,设置了这个标志后,新启动的activity并非就一定在新的task中创建,如果A和B在属于同一个package,而且都是使用默认的taskAffinity,那B还是会在A的task中被创建。 所以,只有A和B的taskAffinity不同时,设置了这个标志才会使B被创建到新的task。

FLAG_ACTIVITY_NO_ANIMATION 禁用切换动画

If set in an Intent passed to Context.startActivity(), this flag will prevent the system from applying an activity transition animation to go to the next activity state. This doesn't mean an animation will never run -- if another activity change happens that doesn't specify this flag before the activity started here is displayed, then that transition will be used. This flag can be put to good use when you are going to do a series of activity operations but the animation seen by the user shouldn't be driven by the first activity change but rather a later one.

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

FLAG_ACTIVITY_NO_HISTORY 不保存Activity的历史状态

If set, the new activity is not kept in the history stack. As soon as the user navigates away from it, the activity is finished. This may also be set with the noHistory attribute.

如果设置这个标志,新的Activity就不会在历史栈中保存。用户一旦离开,这个Activity就会finish掉。也可以使用noHistory属性设置。

FLAG_ACTIVITY_NO_USER_ACTION 不响应onUserLeaveHint方法

If set, this flag will prevent the normal onUserLeaveHint() callback from occurring on the current frontmost activity before it is paused as the newly-started activity is brought to the front.

Typically, an activity can rely on that callback to indicate that an explicit user action has caused their activity to be moved out of the foreground. The callback marks an appropriate point in the activity's lifecycle for it to dismiss any notifications that it intends to display "until the user has seen them," such as a blinking LED.

If an activity is ever started via any non-user-driven events such as phone-call receipt or an alarm handler, this flag should be passed to Context.startActivity, ensuring that the pausing activity does not think the user has acknowledged its notification.

如果设置了这个标志,可以在避免用户离开当前Activity时回调到 onUserLeaveHint(). 通常,Activity可以通过这个回调表明有明确的用户行为将当前activity切出前台。 这个回调标记了activity生命周期中的一个恰当的点,可以用来“在用户看过通知之后”将它们清除,如闪烁LED灯。

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

FLAG_ACTIVITY_PREVIOUS_IS_TOP

If set and this intent is being used to launch a new activity from an existing one, the current activity will not be counted as the top activity for deciding whether the 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 that the current activity will finish itself immediately.

如果启动Activity时设置了这个标志,那当前这个 Activity 不会被当作顶部的 Activity 来判断是否之后新Intent应该被传给栈顶Activity而不是启动一个新的Activity。之前一个的Activity会被当作栈顶,假定当前的Acitvity会立即自己finish掉。

即 A---> B --->C,若B启动C时用了这个标志位,那在启动时B并不会被当作栈顶的Activity,而是用A做栈顶来启动C。此过程中B充当一个跳转页面。

典型的场景是在应用选择页面,如果在文本中点击一个网址要跳转到浏览器,而系统中又装了不止一个浏览器应用,此时会弹出应用选择页面。在应用选择页面选择某一款浏览器启动时,就会用到这个Flag。然后应用选择页面将自己finish,以保证从浏览器返回时不会在回到选择页面。

经常与FLAG_ACTIVITY_FORWARD_RESULT 一起使用。

FLAG_ACTIVITY_REORDER_TO_FRONT 任务中的Activity顺序重排

If set in an Intent passed to Context.startActivity(), this flag will cause the launched activity to be brought to the front of its task's history stack if it is already running.

For example, consider a task consisting of four activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then B will be brought to the front of the history stack, with this resulting order: A, C, D, B. This flag will be ignored if FLAG_ACTIVITY_CLEAR_TOP is also specified.

如果设置了这个标志,而且被启动的Activity如果已经在运行,那这个Activity会被调到栈顶。

比如,一个任务中有4个Activity:A,B,C,D。如果D调用了startActivity() 来启动B时使用了这个标志,那B就会被调到历史栈的栈顶,结果顺序:A,C,D,B,否则顺序会是:A,B,C,D,B。 如果使用了标志 FLAG_ACTIVITY_CLEAR_TOP,那这个FLAG_ACTIVITY_REORDER_TO_FRONT标志会被忽略。

==============================================================================================================================

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED???

If set, and this activity is either being started in a new task or bringing to the top 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 task in the proper state (either moving activities to or from it), or simply resetting that task to its initial state if needed.

如果设置,

FLAG_ACTIVITY_SINGLE_TOP 

If set, the activity will not be launched if it is already running at the top of the history stack.

设置这个标志之后,如果被启动的Activity已经在栈顶,那它就不会被再次启动。

FLAG_ACTIVITY_TASK_ON_HOME 直接返回桌面

If set in an Intent passed to Context.startActivity(), this flag will cause a newly launching task to be placed on top of the current home activity task (if there is one). That is, pressing back from the task will always return the user to home even if that was not the last activity they saw. This can only be used in conjunction with FLAG_ACTIVITY_NEW_TASK.

这个标志可以将一个新启动的任务置于当前的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 的效果一样。

FLAG_DEBUG_LOG_RESOLUTION 打开Activity解析的Log开关

A flag you can enable for debugging: when set, log messages will be printed during the resolution of this intent to show you what has been found to create the final resolved list.

可以用来启用调试的标志:设置以后,在intent的处理过程中log信息会打印出来,可以看到都找到了些什么来创建最终的解析列表。

Log输出如下:

04-15 11:19:09.446: V/IntentResolver(398): Resolving type null scheme null of intent Intent { act=android.intent.action.B_Activity flg=0x8 }
04-15 11:19:09.446: V/IntentResolver(398): Action list: [ActivityIntentInfo{42354338 com.example.icsorigintest.B_Activity}]
04-15 11:19:09.446: V/IntentResolver(398): Matching against filter ActivityIntentInfo{42354338 com.example.icsorigintest.B_Activity}
04-15 11:19:09.446: V/IntentResolver(398):   Filter matched!  match=0x108000
04-15 11:19:09.446: V/IntentResolver(398): Final result list:
04-15 11:19:09.446: V/IntentResolver(398):   ResolveInfo{41ee95d0 com.example.icsorigintest.B_Activity p=0 o=0 m=0x108000}

FLAG_EXCLUDE_STOPPED_PACKAGES 排除已停止的包

If set, this intent will not match any components in packages that are currently stopped. If this is not set, then the default behavior is to include such applications in the result.

设置之后,Intent就不会再匹配那些当前被停止的包里的组件。如果没有设置,默认的匹配行为会包含这些被停止的包。

FLAG_FROM_BACKGROUND 后台启动Activity

Can be set by the caller to indicate that this Intent is coming from a background operation, not from direct user interaction.

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

FLAG_GRANT_READ_URI_PERMISSION 给Activity授权

If set, the recipient of this Intent will be granted permission to perform read operations on the Uri in the Intent's data and any URIs specified in its ClipData.When applying to an Intent's ClipData, all URIs as well as recursive traversals through data or other ClipData in Intent items will be granted; only the grant flags of the top-level Intent are used.

如果设置,Intent的接收者会被授予读权限,用来读取Intent中包含的或是在ClipData中指定的Uri。当被用于Intent中的ClipData时,被授予的是Intent中其它ClipData中的所有Uri和它们递归遍历到的Uri的读权限。只有*Intent中的授予标志会被使用。

FLAG_INCLUDE_STOPPED_PACKAGES 包含已停止的包

If set, this intent will always match any components in packages that are currently stopped. This is the default behavior when FLAG_EXCLUDE_STOPPED_PACKAGES is not set. If both of these flags are set, this one wins (it allows overriding of exclude for places where the framework may automatically set the exclude flag).

设置之后Intent总是会去匹配那些已被停止的包里的组件。如果没有设置 FLAG_EXCLUDE_STOPPED_PACKAGES 标志,那这个就是默认行为。如果两个标志都被设置,那这个会生效(在框架中一些地方可能会自动设置exclude标志,这些标志可以被覆盖掉)。

FLAG_RECEIVER_FOREGROUND 接受器以前台优先级运行

If set, when sending a broadcast the recipient is allowed to run at foreground priority, with a shorter timeout interval. During normal broadcasts the receivers are not automatically hoisted out of the background priority class.

当发送广播的时候设置了这个标志,会允许接收者以前台的优先级运行,有更短的时间间隔。正常广播的接受者是后台优先级,不会被自动提升。

FLAG_RECEIVER_REGISTERED_ONLY 只调用手动注册的接收器(忽略manifest中声明的)

If set, when sending a broadcast only registered receivers will be called -- no BroadcastReceiver components will be launched.

如果发送广播时设置了这个标志,那只会调用注册了的接收器——BroadcastReceiver组件不会被启动。

FLAG_RECEIVER_REPLACE_PENDING 替换掉等待中的广播

If set, when sending a broadcast the new broadcast will replace any existing pending broadcast that matches it. Matching is defined by Intent.filterEquals returning true for the intents of the two broadcasts. When a match is found, the new broadcast (and receivers associated with it) will replace the existing one in the pending broadcast list, remaining at the same position in the list.

This flag is most typically used with sticky broadcasts, which only care about delivering the most recent values of the broadcast to their receivers.

如果在发送广播时设置了这个标志,那新的广播会替换掉那些已存在的相同广播。相同的定义是通过Intent.filterEquals方法对两个广播的Intent处理返回true。 当匹配到相同的,新的广播和对应的接收器会将待发送的广播列表中已存在的替换掉,在列表中保留同样的位置。

这个标志通常被粘性广播(Sticky Broadcast)使用,只保证将最新的广播的值传递给接收器。