您的位置:首页 > 其它

Tasks and Back Stack

2013-10-20 13:00 204 查看
阅读:http://developer.android.com/guide/components/tasks-and-back-stack.html

android通过Task来实现尽管调用了不同程序的Activity但是却让你有一种其他程序的Activity是当前程序的一部分(例如发邮件例子)。

Task就是用户在执行某个任务时各种Activity的集合。


The device Home screen is the starting place for most tasks. When the user touches an icon in the application launcher (or a shortcut on the Home screen), that application's task comes to the foreground. If no task exists for the application (the application has not been used recently), then a new task is created and the "main" activity for that application opens as the root activity in the stack.


  通常来说桌面就是启动Task的地方。当用户点击某个图标的时候,改程序的Task就会被提到前台并被选中,如果改程序的Task不存在,则启用新的Task并把程序的主要ACtivity作为Task的第一个实例。

下面这张图表示了Activity是如何在TAsk里面存在的:




A task is a cohesive unit that can move to the "background" when users begin a new task or go to the Home screen, via the Home button. While in the background, all the activities in the task are stopped, but the back stack for the task remains intact—the task has simply lost focus while another task takes place, as shown in figure 2. A task can then return to the "foreground" so users can pick up where they left off. Suppose, for example, that the current task (Task A) has three activities in its stack—two under the current activity. The user presses the Home button, then starts a new application from the application launcher. When the Home screen appears, Task A goes into the background. When the new application starts, the system starts a task for that application (Task B) with its own stack of activities. After interacting with that application, the user returns Home again and selects the application that originally started Task A. Now, Task A comes to the foreground—all three activities in its stack are intact and the activity at the top of the stack resumes. At this point, the user can also switch back to Task B by going Home and selecting the application icon that started that task (or by selecting the app's task from the recent apps screen). This is an example of multitasking on Android.


  在Task中有前台和后台之分,因为Task不是只有一个。前台的Task的栈顶Activity就是运行中的Activity,而其余的Task都是出于Stopped状态。

  这里有两点需要注意:1、一般创建多个Task的情况是用户不断从桌面启动不同的应用;1、Task以栈低的Activity作为标识,也就是说在Task切换的时候,如果用户从桌面点击某应用并启用了X_Activity,如果系统发现某个Task的栈低是X_Activity,那么系统将不会再启用新的Task而直接使用栈低为X_Activity的Task。


Note: Multiple tasks can be held in the background at once. However, if the user is running many background tasks at the same time, the system might begin destroying background activities in order to recover memory, causing the activity states to be lost. See the following section about Activity state.


  当后台有太多的TAsk而系统内存不足时,TAsk就会被摧毁,而Activity state也都会消失(无法恢复)。


Because the activities in the back stack are never rearranged, if your application allows users to start a particular activity from more than one activity, a new instance of that activity is created and pushed onto the stack (rather than bringing any previous instance of the activity to the top). As such, one activity in your application might be instantiated multiple times (even from different tasks), as shown in figure 3. As such, if the user navigates backward using the Back button, each instance of the activity is revealed in the order they were opened (each with their own UI state). However, you can modify this behavior if you do not want an activity to be instantiated more than once. How to do so is discussed in the later section about Managing Tasks.


  一个Activity有可能会有很多个实例,例如在不同的栈中会有某个Activity的实例,但你也可以通过设置使得Activity只被能被调用一次。


The way Android manages tasks and the back stack, as described above—by placing all activities started in succession in the same task and in a "last in, first out" stack—works great for most applications and you shouldn't have to worry about how your activities are associated with tasks or how they exist in the back stack. However, you might decide that you want to interrupt the normal behavior. Perhaps you want an activity in your application to begin a new task when it is started (instead of being placed within the current task); or, when you start an activity, you want to bring forward an existing instance of it (instead of creating a new instance on top of the back stack); or, you want your back stack to be cleared of all activities except for the root activity when the user leaves the task.


  你可能不想使用系统默认的Task管理机制,那么你可以通过其他的方法来突破这些限制。

  PS:官方不支持这么做,除非你很有必要。

  改变的方法有两种,一种是通过manifest来直接定义,一种是在startActivity的时候定义,如果两者都定义了,第二种优先。

  使用manifest:定义Activity的launchMode属性即可,可选项有:

1、standard,即默认;

2、singleTop:如果当前Task的栈顶就是本Activity,那么执行它的onNewIntent()而不是再次实例化一个Activity。这种Activity可以被多次实例化在不同的栈顶,在一个Task也可以有多个实例;

3、singleTask:只准许一个实例存在,如果实例不存在则启用新的Task并实例化,如果已存在则追寻到该Activity并执行onNewIntent(),浏览器用的就是这个;尽管使用了新的Task,但是当用户返回的时候,仍然跳到之前的Activity。

4、singleInstance:这种是,一个实例独占一个Task,不再有其他的ACtivity存在于这个Task中。

关于上面的第三点我困惑,根据这个文章:/article/5122006.html 可以知道:

正解:1.singleTask 并不一定处于栈底

   2.singleTask 并一定会是栈底的根元素 

   3.singleTask 并不一定会启动新的task  

 情况一:如果在本程序中启动singleTask的activity:假设ActivityA是程序的入口,是默认的模式(standard),ActivityB是singleTask 模式,由ActivityA启动,刚ActivityB不会位于栈底,不是根元素,不会启动新的task,此种情况ActivityB会和ActivityA在一个栈中,位于ActivityA上面

  情况二:如果ActivityB由另外一个程序启动:假设apkA是情况一中的应用,apkB是测试程序,在apkB中启动apkA中的ActivityB,刚ActivityB会位于栈底,是根元素,会启动新的task

注意:singleTask模式的Activity不管是位于栈顶还是栈底,再次运行这个Activity时,都会destory掉它上面的Activity来保证整个栈中只有一个自己,切记切记

也可以通过设置intent的flag来实现。可选参数:

FLAG_ACTIVITY_NEW_TASK:对应singleTask

FLAG_ACTIVITY_SINGLE_TOP:对应singleTop

FLAG_ACTIVITY_CLEAR_TOP:如果当前实例在本Task已经存在,则摧毁其他的Activity来保证这个实例处于TOP状态。

关于清除Task,默认情况下,如果用户很久都没有再使用某个Task,那么系统就清除除了RootActivity之外的所有,可以通过设置Activity的属性来改变这个机制:

1、alwaysRetainTaskState:不管多久都不会修改Task

2、clearTaskOnLaunch:只要用户一离开,整个TAsk都会消失;

3、finishOnTaskLaunch:This attribute is like clearTaskOnLaunch, but it operates on a single activity, not an entire task. It can also cause any activity to go away, including the root activity. When it's set to "true", the activity remains part of the task only for the current session. If the user leaves and then returns to the task, it is no longer present.

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


通过此方法,即可产生新的Task。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: