现在的位置: 首页 > 综合 > 正文

安卓翻译 Tasks and Back Stack (二)

2018年02月18日 ⁄ 综合 ⁄ 共 5945字 ⁄ 字号 评论关闭

接上一篇 

定义登陆类型

登陆类型允许你定义一个activity如何与当前的任务联系在一起。你可以用两种方式来定义不同的登陆类型:

使用manifest文件
当你在你的manifest文件中声明一个activity,你能指定一个activity在被启动时应该怎样与任务关联在一起。

使用intent 标志
当你调用StartActivity()时,你能在Intent中包含一个flag来声明新activity应该怎样(或者是否应该)与当前的任务联系在一起。

像这样,如果Activity A启动了Activity B,Activity B能在它的manifest文件中定义它应该与当前的任务联系在一起(如果它真发生的话)并且Activity A也能要求Activity B怎样与当前的任务关联。如果两个activities都定义了Activity B应该怎样与一个任务关联,那么Activity A的请求(在intent中定义)是高于Activity B的请求(在它的manifest文件中定义)。

注意:一些对manifest文件存在的启动类型可能对intent的标志不存在对应的,同样地,一些对intent的标志存在的登陆类型也不能在manifest中定义。

使用manifest文件

当在你的manifest文件中声明一个activity,你能指定activity应该怎样与一个任务关联起来通过使用<activity>元素的launchMode属性。

launchMode属性指定一个activity应该怎样被启动进入任务的一个说明。这里有四个你不同的你可以安排进launchMode属性的登陆类型:
“standard”(默认类型)
默认。 系统从activity被启动的地方并且传递intnet给它的地方在任务中创建一个新的activity实例。activity能被实例化多次,每个实例能属于不同的任务,而且一个任务能有多个实例。
“singleTop”
如果activity的一个实例已经存在于当前任务的顶部,系统会通过对它的onNewIntent()方法的一个调用传递一个intent给那个实例,而不是创建一个activity新的实例。activity能被实例化多次,每个树立属于不同的任务,而且一个任务也能有多个实例(但是尽在返回栈顶的activity不是一个已经存在activity实例)。
例如,假设一个返回栈由根Activity A,Activities B,C,栈顶的D。对一个activity到来了一个类型D的intent,如果D有着默认“standard”的登陆类型,类的一个新的实例被创建,并且栈变成了A-B-C-D-D。然而,如果D的登陆类型是“singleTop”,那么D的已经存在的实例接收从onNewIntent()的intent,因为在栈顶-栈保存着A-B-C-D。然而,如果一个activity到来了一个类型B的intent,那么B的一个新实例会被添加到栈中,即使它的登陆类型是“singleTop”。

注意:当一个activity的新实例被创建时,用户能通过点击返回键来返回到之前的activity。但是当一个activity的一个已经存在的实例处理一个新的intent时,用户不能点击返回键返回到activity在新的intent到达onNewIntent()的状态。

“singleTask”
系统创建一个新的任务并且实例化了新任务的根activity。然而,如果activity的一个实例已经存在于一个其它的任务中,那么系统将intnet通过对onNewIntent()的一个调用传递给已经存在的实例,而不是创建一个新的实例。在一时段内,activity仅能存在一个实例。
注意:尽管activity在一个新的任务中启动,但是返回键仍然返回给用户之前的activity。

“singleInstance”
与“singleTask”类似,预期让系统不会启动任何其它的拥有实例的activity在这个任务中。activity经常是单独的,并且是它的任务中的仅有成员,任何被这个activity启动的activities都在不同的任务中打开。

像在另外一个例子中,安卓浏览器应用声明web activity应用应该经常在它自己的任务中打开——通过在<activity>元素中指定singleTask登陆模型。这意味着如果你的应用发出一个打开安卓浏览器的intent,它的activity不是被放置在和你的应用同样的任务中。相反,一个新的任务为浏览器启动,或者如果浏览器已经有一个运行于后台的任务,那么这个任务会被带到前台来处理新的intent。

不论一个activity是否在新的任务中启动还是在之前启动它的activity的同一个任务中,返回键总是将用户带回前一个activity。然而,如果你启动一个指定singleTask为登陆模型的activity,那么如果那个activity的一个实例已经存在于后台任务中,那整个任务都会被带回前台。在这个点上,返回栈现在包含了所有从被带回前台的任务的activities。图4展示了这个方案的类型。

图4. 登陆模型为“singleTask”的一个activity怎样被添加到返回栈中的一个展示。如果activity已经是有着自己的返回栈的一个后台任务的一部分,那么整个返回栈都会来到前台,在当前任务的顶部。

关于在manifest文件中使用登陆类型的更多信息,看<activity>元素文档,这里launchMode属性和可被接受的值讨论的更多。

注意:你用launchMode属性给你的activity指定的行为能被包含在启动你的activity的intent中的标志给覆盖,这在

下一章节被讨论。


使用 Intent 标志

当启动一个activity时,你能通过在你传递给startActivity()的intent中包含标志来调整一个activity到它的任务的默认关联。你能用来调整默认行为的标志有:

FLAG_ACTIVITY_NEW_TASK

在新的任务中开启一个activity。如果你正在启动的这个activity相应的任务正在运行着,这个任务会被带到前台同时它的最后的状态也会被恢复,并且activity在onNewIntent()中接收新的intent。

这和“singleTask”launchMode值产生同样的行为,像在前一个章节中讨论的那样。

FLAG_ACTIVITY_SINGLE_TOP

如果被开启的activity是当前的activity(在返回栈顶的),那么已经存在的实例接收一个对onNewIntent()的调用,代替创建一个新的activity实例。

这和“singleTop”launchMode值产生同样的行为,在前面的章节中讨论过。

FLAG_ACTIVITY_CLEAR_TOP

如果被开启的activity已经存在于当前的任务中,那么代替登陆一个新的这个activity的实例,在这个activity上面的所有activity会被销毁并且这个intent被传递给这个activity重新呈现的实例(现在是在顶部,通过onNewIntent())。

这个就没有与其相对应的产生这个行为的launchMode属性的值了。


FLAG_ACTIVITY_CLEAR_TOP 经常用于与FLAG_ACTIVITY_NEW_TASK结合使用。当他们被用于彼此的时候,这些标志是一个在其他任务中定位一个已经存在的activity的方式,并且把它放在它可以对intent回应的地方。

注意:如果被指定的activity登陆类型是标准的,它也被从栈中移除,在它的位置一个新的实例也被生成来处理将要到来的intent。这是因为一个新的实例经常因一个新的intnet被创建当登陆类型是“standard”。


处理相似度

相似度指示了一个activity更倾向于属于哪个任务。默认情况下,从同一个应用出来的activities相互之间都有一个相似度。因此,默认情况下,在同一个应用中的所有activities更倾向于在同一个任务中。然而,你能自己调整一个activity的默认亲密度。在不同应用中定义的activities能共享一个相似度,或者在同一个应用中定义的activities能被安排不同的任务相似度


你能通过使用<activity>元素中的taskActivity属性对一个给定的activity来调整相似度。


taskActivity属性携带了一个字符串值,这个值必须是独一无二的且来自于声明在<manifest>元素中的默认包名,因为系统用那个名字来为应用定义默认的任务相似度。

相似度在两种环境下起作用:

当包含FLAG_ACTIVITY_NEW_FLAG标志的intent启动一个activity。

一个新的activity,默认情况下,会被安排进调用startActivity()的activity的任务中。它被压入想调用者一样的返回栈中。然而,如果传递给startActivity()的intent包含FLAG_ACTIVITY_NEW_FLAG标志,系统会寻找一个不同的任务来装载新的activity。它经常是个新任务。然而,它不是必须的。如果有一个与新activity有着相同相似度的已经存在的任务,activity会被装进这个任务中。如果没有,它就会开始个新任务。

如果这个标志引起一个activity开始个新任务并且用户点击主页键离开它,这儿必须有一些对用户来说能导航返回到任务的方式。一些入口(例如通知管理栏)经常在外部的任务中开启activities,从来不会作为它们的一部分,因此它们经常将FLAG_ACTIVITY_NEW_TASK放在传递给startActivity()的intents中。如果你有一个能被外面可能使用这个标志唤醒的activity,当心用户有一个独立的能够返回被启动任务的方式,例如桌面上的图标(任务的根activity有一个CATEGORY_LAUNCHERintent过滤器,看Starting
a task 章节)。

当一个activity的allowTaskReparenting 属性是“true”

在这情况下,activity能从它开启的任务有着相似度的任务中离开(the activity can move from the task it
starts to the task it has an affinity for,原话是这个,我看晕了)
,当一个任务来到前台时。

例如,假定一个报告在被选择的城市的天气状况activity被定义成一个旅行应用的一部分。它在同样的应用中有与其它activities相同的相似度(默认的应用相似度)并且它也允许用这个属性重定父极。当你的activities中的一个开启了天气报告的activity,它最开始属于和你的activity相似的任务中,然而,当旅行应用的任务来到前台后,天气报告的activity会被重新安排到任务中,并且在这个中来呈现它。

注意:如果一个.apk文件从用户的视角看包含超过一个“应用”,你可能想用taskAffinity属性给activities安排不同的相似度来让它们关联每个“应用”。


清除返回栈

如果用户离开一个任务很长时间,系统会清除掉出了根activity以外的所有activities。当用户又返回任务时,仅有根activity被重新恢复。系统这样做是因为在一大段时间后,用户可能放弃他们之前做的事情并且返回任务做一些新的事情。

这里有一些你能用来调整这个行为的activity属性:

alwaysRetainTaskState

如果这个属性在一个任务的根activity中被设置为“true”,被描述的默认行为就不会发生。在长时间后,任务在它的栈中保存着所有的activities。

clearTaskOnLaunch

如果这个属性在一个任务的根activity中被设置为“true”,栈就会被清除到直到根activity不论用户什么时候离开任务和返回它。换句话说,它是alwaysRetainTaskS的反面。用户经常在它的初始状态返回到任务,甚至仅仅在离开任务一小会。

finishOnTaskLaunch

这个属性像clearTaskLaunch,但它仅对一个单独activity有效,不是所有的任务。它也能因此任何activity离开,包括根activity。当它被设置为“true”时,activity仅为当前的会话保存任务的部分。如果用户离开然后再返回任务,它不在呈现。


开启一个任务

你能通过给出一个特定的被指定为行为“android.intent.action.MAIN”和被指定分类“android.intent.category.LAUNCHER”的intent过滤器来将一个activity设置成一个任务的入口。例如:

<activity ... >
    <intent-filter ... >
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    ...
</activity>

这种的intent过滤器在应用桌面上会为activity产生一个图标和标签,给用户一个登陆activity和在它被登陆后任何时间创建的任务的方式。

这第二个任务是重要的:用户必须能够离开任务然后用activity桌面返回到它。出于这个原因,两个经常标志activity初始化一个任务的登陆类型,"singleTask" and
"
"singleInstance",应该仅在activity有ACTION_MAIN 和
a
CATEGORY_LAUNCHER 过滤器时使用。例如,设想一下,如果过滤器丢失会发生什么:一个intent启动一个“singleTask”activity,初始一个新任务,用户话费一些时间在那个栈中工作。用户然后按下了主页键。任务现在被送回后台并不再可见。现在用户没有返回到任务的方式,因为它没有在应用桌面中呈现。


对那些你不想让用户成功返回activity的例子,设置<activity>元素的finishOnTaskLaunch成“true”(看清除栈)。

这节可翻译完了。你们要是看完了,可否给个评论?好的坏的都行,只要让我知道我翻译的东西有个存在感就行。

我个人翻译的好无力啊啊啊啊啊啊啊啊

抱歉!评论已关闭.