`
bcyy
  • 浏览: 1819066 次
文章分类
社区版块
存档分类
最新评论

Android 任务和回退堆栈---默认启动模式

 
阅读更多
启动模式允许你定义一个新的Activity实例如何跟当前的任务进行关联。以下两种方法能够定义不同的启动模式:

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的位置。

注:本人转载系个人觉得翻译的很好,值得收藏,且自己回头看着方便。

如有兴趣请访问作者官方博客http://blog.csdn.net/FireOfStar

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics