android学习笔记(二)

Activities and Tasks

一个活动能启动另一个活动,甚至是在别的应用程序中定义的活动。设想,例如,您想让用户显示某地的街区地图。而且已经有了一个可以完成此事的活动,所以您的活动要做的仅仅是将请求信息放进一个Intent对象中,将这个Intent对象传递给startActivity()。地图查看器这个活动就会显示出地图。当用户点击BACK按钮之后,您的活动就会重新出现在屏幕上。

    对用户来说这个地图查看器就好像您的应用程序中的活动一样,虽然这个地图查看器是定义在其他应用程序中而且运行在那个应用程序的进程中。Android将您的活动和那个借用的活动放在同一个task中,以维持用户体验。简单来讲任务就是用户觉得好像是一个“应用程序”的东西。任务就是以栈的形式组织起来起来的相互关联的一组活动。栈中最底部的是任务的起始活动——一般是用户在滑出的程序列表中选择启动的活动。最顶部的是正在运行的活动——用户正在关注操作的。当一个活动开启另一个时,新启动的活动被压入栈中;并且成为正在运行的活动。旧一个活动还在栈中。当用户按下BACK键后,正在运行的活动被弹出栈,旧一个恢复成为正在运行的活动。
It's a group of related activities, arranged in a stack. The root activity in the stack is the one that began the task — typically, it's an activity the user selected in the application launcher. The activity at the top of the stack is one that's currently running — the one that is the focus for user actions. When one activity starts another, the new activity is pushed on the stack; it becomes the running activity. The previous activity remains in the stack. When the user presses the BACK key, the current activity is popped from the stack, and the previous one resumes as the running activity.

    任务是由栈中的活动组成的,而不是清单文件中声明的某个类或元素。所以无法单独为一个任务设定确定的活动的信息。任务的所有信息都是设定在根活动中的。例如,下一个章节会讲到“任务的亲和度”;亲和度信息就是从任务的根活动中获取的。
A task is a stack of activities, not a class or an element in the manifest file. So there's no way to set values for a task independently of its activities. Values for the task as a whole are set in the root activity. For example, the next section will talk about the "affinity of a task"; that value is read from the affinity set for the task's root activity.

    任务中的所有活动是作为一个整体运转的。整个任务(一个栈的所有活动)可以被送到前台或推到后台。假设,例如,现在有一个正在运行的任务,栈中有四个活动 ——正在运行的活动下边有三个,这是用户按下了HOME键,回到了应用程序的列表然后运行了一个新的应用程序(事实上,是一个新的任务)。则旧一个任务就被推到了后台,新一个任务的根活动被现实。一段时间过后用户回到了应用程序列表,又选择了旧一个应用程序(旧一个任务)。则旧一个任务的所有栈中的四个活动就都被送到了前台。这时用户如果按下BACK建屏幕不会回到用户刚离开的活动(就是新一个任务的跟活动)。而是旧一个任务的栈顶活动被弹出,下一个活动顶上,并被显示出来。
All the activities in a task move together as a unit. The entire task (the entire activity stack) can be brought to the foreground or sent to the background. Suppose, for instance, that the current task has four activities in its stack — three under the current activity. The user presses the HOME key, goes to the application launcher, and selects a new application (actually, a new task). The current task goes into the background and the root activity for the new task is displayed. Then, after a short period, the user goes back to the home screen and again selects the previous application (the previous task). That task, with all four activities in the stack, comes forward. When the user presses the BACK key, the screen does not display the activity the user just left (the root activity of the previous task). Rather, the activity on the top of the stack is removed and the previous activity in the same task is displayed.

   上面描述的过程是活动和任务的默认动作流程。但是那个流程很多方面都是可修改的。活动和任务的组合还有任务中的活动是由开启活动的Intent对象中设定的控制标 和 清单文件中活动的<activity>元素的属性共同控制的。
The behavior just described is the default behavior for activities and tasks. But there are ways to modify almost all aspects of it. The association of activities with tasks, and the behavior of an activity within a task, is controlled by the interaction between flags set in the Intent object that started the activity and attributes set in the activity's <activity> element in the manifest. Both requester and respondent have a say in what happens.

In this regard, the principal Intent flags are:

这种情况下,重要的Intent控制标有:

FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP

The principal <activity> attributes are:

重要的<activity>属性有:

taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch

下面的章节描述了这些控制标和属性的作用,如何相连发生作用,在使用过程中的注意事项。
The following sections describe what some of these flags and attributes do, how they interact, and what considerations should govern their use.

Affinities and new tasks——亲和度和新任务

    默认的,一个应用程序中的所有活动之间都互有   亲和度——就是他们属于一个任务的优先权。但是,您可以通过每个活动的<activity>元素的taskAffinity属相为某个活动设定单独的亲和度。不同程序中定义的活动可以共享一个亲和度,一个应用程序中的不同活动可以定义不同的亲和度。亲和度在两种情况下有用:一种情况是当激活活动的Intent对象包含了FLAG_ACTIVITY_NEW_TASK控制标,另一种情况是活动将allowTaskReparenting属性设置为了"true"。
By default, all the activities in an application have an affinity for each other — that is, there's a preference for them all to belong to the same task. However, an individual affinity can be set for each activity with the taskAffinity attribute of the <activity> element. Activities defined in different applications can share an affinity, or activities defined in the same application can be assigned different affinities. The affinity comes into play in two circumstances: When the Intent object that launches an activity contains the FLAG_ACTIVITY_NEW_TASK flag, and when an activity has its allowTaskReparenting attribute set to "true".

The FLAG_ACTIVITY_NEW_TASK flag——FLAG_ACTIVITY_NEW_TASK控制标
   正如上边提到的,默认情况下,调用startActivity()向任务中添加一个活动。新添加的活动会压入添加他的活动所在栈。但是,如果传递给startActivity()的Intent对象中含有FLAG_ACTIVITY_NEW_TASK控制标,系统会将新活动压入别的栈。通常,就像控制标的字面意思一样,会是一个新的任务。但是,不是一定要压入新的栈。如果已经有了一个亲和度和新活动相同的任务,活动就被压入那个任务的栈中。如果没有,才会新建任务。
As described earlier, a new activity is, by default, launched into the task of the activity that called startActivity(). It's pushed onto the same stack as the caller. However, if the Intent object passed to startActivity() contains the FLAG_ACTIVITY_NEW_TASK flag, the system looks for a different task to house the new activity. Often, as the name of the flag implies, it's a new task. However, it doesn't have to be. If there's already an existing task with the same affinity as the new activity, the activity is launched into that task. If not, it begins a new task.

The allowTaskReparenting attribute——allowTaskReparenting属性
    如果活动将allowTaskReparenting属性设为"true",他可以    在具有亲和度的任务被送到前台时   从开启他的任务移到亲和的任务中。例如,假设有一个已经做好的旅行的应用程序,定义了一个报告选择的城市的天气情况的活动。这个活动和这个应用程序中其他活动有相同亲和度(默认的亲和度),同时允许重定父级。您自己的一个应用程序中的一个活动开启了这个天气报告活动,他初始情况是处于您自己的应用程序的任务中。但是当这个旅行应用程序运行并被切换到前台后,天气报告活动就会被重新连接    到旅行应用程序中,并在那个任务中显示。

If an activity has its allowTaskReparenting attribute set to "true", it can move from the task it starts in to the task it has an affinity for when that task comes to the fore. For example, suppose that an activity that reports weather conditions in selected cities is defined as part of a travel application. It has the same affinity as other activities in the same application (the default affinity) and it allows reparenting. One of your activities starts the weather reporter, so it initially belongs to the same task as your activity. However, when the travel application next comes forward, the weather reporter will be reassigned to and displayed with that task.

    如果一个.apk 文件包含了多个用户看来的“应用程序”,您可能会为和每个“应用程序”相关的活动设定不同的亲和度。
If an .apk file contains more than one "application" from the user's point of view, you will probably want to assign different affinities to the activities associated with each of them.

Launch modes——启动模式

下面是可以被设为<activity>元素launchMode属性的四种启动模式:
There are four different launch modes that can be assigned to an <activity> element's launchMode attribute:

"standard" (the default mode) ——标准(默认的)
"singleTop"
"singleTask"
"singleInstance"

每个模式都有以下四方面的特点:
The modes differ from each other on these four points:

1.  响应Intent的活动会被装入哪个任务。在"standard"和"singleTop"模式,是装入发Intent(调用了startActivity())的任务——除非Intent对象含有FLAG_ACTIVITY_NEW_TASK控制标。后种情况流程如前边Affinities and new tasks章节所述。
1.Which task will hold the activity that responds to the intent. For the "standard" and "singleTop" modes, it's the task that originated the intent (and called startActivity()) — unless the Intent object contains the FLAG_ACTIVITY_NEW_TASK flag. In that case, a different task is chosen as described in the previous section, Affinities and new tasks.
   相反的,使用"singleTask"标记和"singleInstance"标记始终为根活动的活动。开启这样的活动会新建一个任务;而不是装入某个正在运行的任务。
In contrast, the "singleTask" and "singleInstance" modes mark activities that are always at the root of a task. They define a task; they're never launched into another task.

2.  是否允许产生多个活动实例。2一个"standard"或"singleTop"活动可以被多次实例化。他们可以属于多个任务,同样的活动可以在一个确定的任务中有多个实例。
2.Whether there can be multiple instances of the activity. A "standard" or "singleTop" activity can be instantiated many times. They can belong to multiple tasks, and a given task can have multiple instances of the same activity.
    相反的,"singleTask和"singleInstance"的活动只能有一个实例。因为这些活动是任务的根活动,这种限制意味着一个任务在同一时间只能有一个。
In contrast, "singleTask" and "singleInstance" activities are limited to just one instance. Since these activities are at the root of a task, this limitation means that there is never more than a single instance of the task on the device at one time.

3.   所在任务中是否允许有其他活动。"singleInstance"活动单独运行在一个任务中。如果他开启另一个活动,新一个活动不论启动模式都会运行在新任务中——就好像用带有FLAG_ACTIVITY_NEW_TASK控制标的Intent对象激活似的。其他方面"singleInstance"与"singleTask"相同。
3.Whether the instance can have other activities in its task. A "singleInstance" activity stands alone as the only activity in its task. If it starts another activity, that activity will be launched into a different task regardless of its launch mode — as if FLAG_ACTIVITY_NEW_TASK was in the intent. In all other respects, the "singleInstance" mode is identical to "singleTask".
   另外三个模式允许任务中存在多个活动。"singleTask"活动将总是任务的根活动,但是由他启动的其他活动会被装入他所在的任务。"standard"和"singleTop"活动能在任务栈中任何任何位置出现。
The other three modes permit multiple activities to belong to the task. A "singleTask" activity will always be the root activity of the task, but it can start other activities that will be assigned to its task. Instances of "standard" and "singleTop" activities can appear anywhere in a stack.

4.   获得新意图时是否使用新   类的   实例来操作。对于默认"standard"的模式,每次获得新意图时都会用新的实例响应。每个实例响应一个意图。"singleTop"模式中,如果意图响应类实例存在且在   意图的目标任务   栈的栈顶,那么意图响应类实例将会被重用。如果存在但不再栈顶,则不会被重用。新实例被创建并压入栈顶。
4.Whether a new instance of the class will be launched to handle a new intent. For the default "standard" mode, a new instance is created to respond to every new intent. Each instance handles just one intent. For the "singleTop" mode, an existing instance of the class is re-used to handle a new intent if it resides at the top of the activity stack of the target task. If it does not reside at the top, it is not re-used. Instead, a new instance is created for the new intent and pushed on the stack.
    例如,假设 一个任务的几个活动是   根活动A,活动B,C,D   的顺序,栈内就是A-B-C-D。这时收到一个类D进行响应的意图。如果D是"standard"启动模式,则将创建类的新实例,栈内变成A-B-C-D-D。但是如果D是"singleTop"启动模式,用以响应新意图的实例已经存在(而且已经在栈顶),栈保持A-B-C-D不变。
For example, suppose a task's activity stack consists of root activity A with activities B, C, and D on top in that order, so the stack is A-B-C-D. 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 is expected to handle the new intent (since it's at the top of the stack) and the stack remains A-B-C-D.
    如果,另一种情况,收到一个类B响应的意图,不管B的启动类型是"standard"还是"singleTop"(因为B不在栈顶),新实例都会被创建,之后的栈会变成A-B-C-D-B。
If, on the other hand, the arriving intent is for an activity of type B, a new instance of B would be launched no matter whether B's mode is "standard" or "singleTop" (since B is not at the top of the stack), so the resulting stack would be A-B-C-D-B.
    就像前面已经提到过的,"singleTask"和"singleInstance"活动的类永远不可能会出现多个实例。所以他们的类就会处理所有的收到的意图。"singleInstance"活动永远是任务的栈的最顶活动(因为他是任务中的唯一活动),因此他也总可以处理一个意图。但是在"singleTask"活动栈位之上可能也可能没有另外的活动。如果有,那么他就不能对新到的意图进行处理,这个意图就丢失了。(即使意图已经丢失,意图的收到也会出发任务使其被送到并保持在前台。)
As noted above, there's never more than one instance of a "singleTask" or "singleInstance" activity, so that instance is expected to handle all new intents. A "singleInstance" activity is always at the top of the stack (since it is the only activity in the task), so it is always in position to handle the intent. However, a "singleTask" activity may or may not have other activities above it in the stack. If it does, it is not in position to handle the intent, and the intent is dropped. (Even though the intent is dropped, its arrival would have caused the task to come to the foreground, where it would remain.)

    当一个已有的活动被请求去处理一个新的意图,Intent对象会通过onNewIntent()的调用传递给这个活动。(传递进来的原始的Intent对象可以通过调用getIntent()获取。)
When an existing activity is asked to handle a new intent, the Intent object is passed to the activity in an onNewIntent() call. (The intent object that originally started the activity can be retrieved by calling getIntent().)

    注意,当创建一个新的Activity类的实例来处理一个新收到的意图时,用户可以按BACK键回到上一个状态(上一个活动)。但是使用一个已有的Activity类实例操作新收到的意图时,用户不能通过按下BACK键回到这个实例在接受到新意图之前的状态。
Note that when a new instance of an Activity is created to handle a new intent, the user can always press the BACK key to return to the previous state (to the previous activity). But when an existing instance of an Activity handles a new intent, the user cannot press the BACK key to return to what that instance was doing before the new intent arrived.

启动模式的更多信息,参见清单文件<activity>元素的描述。
For more on launch modes, see the description of the <activity> element

猜你喜欢

转载自chenqiang5206.iteye.com/blog/1625151