1.使用清单文件
当在清单文件中声明一个Activity时,你能够指定这个Activity在启动时应该如何跟任务进行关联。
2. 使用Intent标识
在调用startActivity()方法时,你能够在Intent中包含一个标识,用来声明这个新的Activity应该如何跟当前的任务进行关联。
因此,如果Activity A启动Activity B,Activity B能够在它的清单文件中定义它应该怎样跟当前的任务进行关联,并且Activity A也能够请求Activity B应该怎样跟当前的任务进行关联。如果这两个Activity都定义了Activity B应该怎样跟当前任务关联,那么Activity A的请求(在Intent中定义的)的优先级要高于Activity B的请求(在清单文件中定义的)。
注意:某些在清单文件中有效的启动模式对Intent标识是无效的,同样某些针对Intent标识有效的启动模式也不能在清单文件中定义。
使用清单文件
在清单文件中声明一个Activity时,你能够使用<activity>元素的launchMode属性来指定这个Activity应该怎样跟一个任务关联。launchMode属性会指定一个有关这个Activity应该如何被加载到一个任务中的指令。有四种不同的启动模式能够跟这个属性进行匹配:
“standard”(默认模式)
默认情况下,系统会在任务中启动和传递Intent的地方创建一个新的Activity实例。这个Activity可以被实例化多次,每个实例属于不同的任务,并且一个任务也可以有多个实例。
“singTop”
如果这个Activity的实例在当前任务的顶部已经存在,那么系统就会通过调用onNewIntent()方法把这个Intent传递给这个实例,而不是创建一个新的实例。这个Activity可以被实例化多次,每个实例属于不同的任务,并且一个任务可以有多个实例(只有回退堆栈顶部的Activity不是这个既存的Activity的实例时才会有多个实例存在)。
例如,假设一个任务的回退堆栈由跟Activity A和Activity B、Activity C以及在顶部的Activity D组成。一个针对D类型Activity的Intent访问,如果D有默认的“standard”启动模式,那么这个类就会有一个新的实例被启动,并且堆栈变成A-B-C-D-D的组合。但是如果D的启动模式是“singleTop”,那么既存的D的实例因为它在堆栈的顶部,所以会接收通过onNewIntent()方法传递的Intent,堆栈仍然保持着A-B-C-D的组合。但是,如果针对访问B类型Activity的Intent,那么即使它的启动模式是“singleTop”,也会有一个新的B的实例被添加到堆栈中。
注意:当一个新的Activity实例被创建时,用户能够按回退按钮返回到前一个Activity。但是当一个既存的Activity实例处理了一个新的Intent,那么用户不能按回退按钮返回到接受新的Intent访问之前的Activity的状态。
“singleTask”
系统创建一个新的任务并且在这个新任务的根实例化这个Activity。但是,如果在另一个任务中已经存在了这个Activity的实例,系统会通过onNewIntent()方法把Intent传递到这个既存的实例,而不是创建一个新的实例。这个Activity的实例智能存在一次。
注意:尽管这个Activity在一个新的任务中启动,但是按下返回按钮时依然返回到前一个Activity。
“singleInstance”
除了系统不在拥有这个实例的任务中启动其他任何的Activity之外,与“singleTask”模式相同。这个Activity总是单独的并且是它的任务的唯一成员,任何通过这个Activity启动的Activity都在一个独立的任务中打开。
例如,Android浏览器应用程序通过在<activity>元素中指定singleTask启动模式来声明这个浏览器Activity应该总是在它自己的任务中打开。这就意味着如果你的应用程序发布了一个打开Android浏览器的Intent,那么这个浏览器的Activity不会被放在与你的应用一样的任务中,相反,会启动一个新的浏览器任务,如果这个浏览器已经在后台运行,那么这个任务会被带到前台,以便处理新的Intent。
无论是在一个新的任务中启动一个Activity,还是跟启动它的Activity在同一个任务中,按下回退按钮后总会把用户带到前一个Activity。但是如果你启动了指定了singleTask启动模式的Activity,然后如果那个Activity的实例存在于一个后台任务中,那么整个任务就会被带到前台。在这个时点,在这个堆栈的顶部,回退堆栈包含了从这个任务中提取的所有的Activity。图4说明这种场景类型
图4.显示了一个带有“singleTask”启动模式的Activity是怎样被添加到回退堆栈中,如果这个Activity是一个已经存在的拥有自己回退堆栈的后台任务的一部分,那么整个回退堆栈也会被带到前面来,放到当前任务堆栈的顶部。
关于在清单文件中使用启动模式的更多信息,请查阅<activity>元素文档中launchMode属性和属性值的讨论。
注意:用launchMode属性给Activity指定的属性能够被启动Activity的Intent所包含的标识覆盖。
使用Intent标识
启动Activity时,你能够通过在传递给startActivity()方法的Intent中包含标识来修改Activity的默认启动模式,使用以下标识能够修改Activity的默认行为:
FLAG_ACTIVITY_NEW_TASK:
在一个新的任务中启动Activity,如果这个正在启动的Activity是一个已经运行的任务,那么这个任务联通最后被保存的状态一起被提取到前台,并且接受onNewIntent()方法中的新的Intent。
这个过程与launchMode属性值等于singleTask时具有同样的行为。
FLAG_ACTIVITY_SINGLE_TOP:
如果正在启动的Activity是当前的Activity(在回退堆栈的顶部),那么这个既存的实例会接受一个对onNewIntent()方法的调用,而不是创建一个新的Activity实例。
这个过程与launchMode属性值等于singleTop时具有同样的行为。
FLAG_ACTIVITY_CLEAR_TOP:
如果正在被启动的Activity已经运行在当前的任务中,那么就不会启动这个Activity的一个新的实例,而是销毁回退堆栈中这个Activit之上的所有其他Activity,并且通过onNewIntent()方法,把这个Intent传递给要恢复的Activity的实例(目前它在堆栈的顶部)。
对于launchMode属性没有响应值对应这个行为过程。
FLAG_ACTIVITY_CLEAR_TOP经常会结合FLAG_ACTIVITY_NEW_TASK标记使用,当它们一起使用时,这些标识是在另一个任务中定位一个既存的Activity的方法,并且会把这个Activity放到一个能够响应Intent的位置。