Understand Tasks and Back Stack--Defining launch modes


#Defining launch modes
Launch modes allow you to define how a new instance of an activity is associated with the current task. You can define different launch modes in two ways:

Using the manifest file
When you declare an activity in your manifest file, you can specify how the activity should associate with tasks when it starts.

Using Intent flags
When you call startActivity(), you can include a flag in the Intent that declares how (or whether) the new activity should associate with the current task.

As such, if Activity A starts Activity B, Activity B can define in its manifest how it should associate with the current task (if at all) and Activity A can also request how Activity B should associate with current task. If both activities define how Activity B should associate with a task, then Activity A’s request (as defined in the intent) is honored over Activity B’s request (as defined in its manifest).1

Note: Some launch modes available for the manifest file are not available as flags for an intent and, likewise, some launch modes available as flags for an intent cannot be defined in the manifest.

1、Using the manifest file

When declaring an activity in your manifest file, you can specify how the activity should associate with a task using the activity element’s launchMode attribute.

The launchMode attribute specifies an instruction on how the activity should be launched into a task. There are four different launch modes you can assign to the launchMode attribute:

“standard” (the default mode)

Default. The system creates a new instance of the activity in the task from which it was started and routes the intent to it. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances.

“singleTop”

If an instance of the activity already exists at the top of the current task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances (but only if the activity at the top of the back stack is not an existing instance of the activity).
For example, suppose a task’s back stack consists of root activity A with activities B, C, and D on top (the stack is A-B-C-D; D is on top). An intent arrives for an activity of type D. If D has the default “standard” launch mode, a new instance of the class is launched and the stack becomes A-B-C-D-D. However, if D’s launch mode is “singleTop”, the existing instance of D receives the intent through onNewIntent(), because it’s at the top of the stack—the stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new instance of B is added to the stack, even if its launch mode is “singleTop”.

Note: When a new instance of an activity is created, the user can press the Back button to return to the previous activity. But when an existing instance of an activity handles a new intent, the user cannot press the Back button to return to the state of the activity before the new intent arrived in onNewIntent().

“singleTask”

The system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its onNewIntent() method, rather than creating a new instance. Only one instance of the activity can exist at a time.

Note: Although the activity starts in a new task, the Back button still returns the user to the previous activity.

“singleInstance”

Same as “singleTask”, except that the system doesn’t launch any other activities into the task holding the instance. The activity is always the single and only member of its task; any activities started by this one open in a separate task.

As another example, the Android Browser app declares that the web browser activity should always open in its own task—by specifying the singleTask launch mode in the element. This means that if your app issues an intent to open the Android Browser, its activity is not placed in the same task as your app. Instead, either a new task starts for the Browser or, if the Browser already has a task running in the background, that task is brought forward to handle the new intent.

Regardless of whether an activity starts in a new task or in the same task as the activity that started it, the Back button always takes the user to the previous activity. However, if you start an activity that specifies the singleTask launch mode, then if an instance of that activity exists in a background task, that whole task is brought to the foreground. At this point, the back stack now includes all activities from the task brought forward, at the top of the stack. Figure 4 illustrates this type of scenario.2

在这里插入图片描述
Figure 4. A representation of how an activity with launch mode “singleTask” is added to the back stack. If the activity is already a part of a background task with its own back stack, then the entire back stack also comes forward, on top of the current task.

For more information about using launch modes in the manifest file, see the element documentation, where the launchMode attribute and the accepted values are discussed more.

Note: The behaviors that you specify for your activity with the launchMode attribute can be overridden by flags included with the intent that start your activity, as discussed in the next section.3

2、Using Intent flags

When starting an activity, you can modify the default association of an activity to its task by including flags in the intent that you deliver to startActivity(). The flags you can use to modify the default behavior are:

FLAG_ACTIVITY_NEW_TASK

Start the activity in a new task. If a task is already running for the activity you are now starting, that task is brought to the foreground with its last state restored and the activity receives the new intent in onNewIntent().
This produces the same behavior as the “singleTask” launchMode value, discussed in the previous section.

FLAG_ACTIVITY_SINGLE_TOP

If the activity being started is the current activity (at the top of the back stack), then the existing instance receives a call to onNewIntent(), instead of creating a new instance of the activity.
This produces the same behavior as the “singleTop” launchMode value, discussed in the previous section.

FLAG_ACTIVITY_CLEAR_TOP

If the activity being started 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 are destroyed and this intent is delivered to the resumed instance of the activity (now on top), through onNewIntent()).
There is no value for the launchMode attribute that produces this behavior.

FLAG_ACTIVITY_CLEAR_TOP is most often used in conjunction with FLAG_ACTIVITY_NEW_TASK. When used together, these flags are a way of locating an existing activity in another task and putting it in a position where it can respond to the intent.

Note: If the launch mode of the designated activity is “standard”, it too is removed from the stack and a new instance is launched in its place to handle the incoming intent. That’s because a new instance is always created for a new intent when the launch mode is “standard”.4

参考文档:https://developer.android.com/guide/components/activities/tasks-and-back-stack#TaskLaunchModes


  1. 当Activity A 启动Activity B时,如果Activity B在manifest中定义了launch mode 并​且 Activity A在启动Activity B时使用的Intent也设置了Intent flags,则​​​​​最终应当遵从Intent flags中设定的行为。 ↩︎

  2. 特别注意一下该行为。 ↩︎

  3. Activity使用launchMode指定的启动行为(在AndroidManifest.xml文件中使用标签指定launchMode)可被启动该Activity的Intent指定的启动行为(使用Intent flags指定)覆盖,即Intent flags 指定的启动行为优先于Manifest文件中指定的launchMode; ↩︎

  4. 使用 Intent(Intent flags 为FLAG_ACTIVITY_CLEAR_TOP) 启动Activity A(其launch mode是“standard”)时,则current stack中的Activity A的实例将会被移除,并启动一个新的实例来响应该Intent。因为当launch mode是“standard”时,总是创建一个新实例来响应 new intent. ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值