Android 阅读Tasks and Back Stack文章后的重点摘抄
这篇文章是做android的必读篇目,要仔细阅读,原文连接http://developer.android.com/guide/components/tasks-and-back-stack.html
另外一篇 http://developer.android.com/guide/topics/manifest/activity-element.html#clear
先看一看task和back stack的定义:
A task is a collection of activities that users interact with when performing a certain job. The activities are arranged in a stack (the "back stack"), in the order in which each activity is opened.
1.
Activities in the stack are never rearranged, only pushed and popped from the stack—pushed onto the stack when started by the current activity and popped off when the user leaves it using the Back button.
注意这句,明确指出activity是不能重新调整顺序的,比如,有一个task中有a ,b ,c 我想通过intent等方法把stack底的a实例移到最上边现实出来,这样的功能是实现不了的!这样的需求应该通过其他方法解决,比如再建立一个a实例。
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 theHome 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。
back stack 保存了task中的所有activity,当新task启动后,原有task的整个back stack会被移入后台。
3.
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.
You can do these things and more, with attributes in the <activity>
manifest element and with flags in the intent that you pass to startActivity()
.
In this regard, the principal <activity>
attributes you can use are:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch
And the principal intent flags you can use are:
4.一下内容十分重要,也比较长,要耐心仔细阅读
Defining launch modes
Launch modes allow you to define how a new instance of an activity is associated with the current task. You can define different launch modes in two ways:
- Using the manifest file
When you declare an activity in your manifest file, you can specify how the activity should associate with tasks when it starts.
- Using Intent flags
When you call
startActivity()
, you can include a flag in theIntent
that declares how (or whether) the new activity should associate with the current task.
这里需要注意,提到的这2种方式仅仅影响launch mode,还有许多task调整相关的方法不与上面这2个东西相关,比如 android:clearTaskOnLaunch,请参看 http://developer.android.com/guide/topics/manifest/activity-element.html#clear
As such, if Activity A starts Activity B, Activity B can define in its manifest how it should associate with the current task (if at all) and Activity A can also request how Activity B should associate with current task. If both activities define how Activity B should associate with a task, then Activity A's request (as defined in the intent) is honored over Activity B's request (as defined in its manifest).
注意这里,如果同时通过intent 和 launch mode 定义启动方式,会以intent的为准。如果不冲突的话,会取交集吗?
Note: Some launch modes available for the manifest file are not available as flags for an intent and, likewise, some launch modes available as flags for an intent cannot be defined in the manifest.
这里说的是,launch modes 和intent 都有独特的启动方式,互相是不包涵的。
Using the manifest file
When declaring an activity in your manifest file, you can specify how the activity should associate with a task using the <activity>
element's launchMode
attribute.
The launchMode
attribute specifies an instruction on how the activity should be launched into a task. There are four different launch modes you can assign to the launchMode
attribute:
"standard"
(the default mode)- Default. The system creates a new instance of the activity in the task from which it was started and routes the intent to it. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances.
"singleTop" 在task顶端保持唯一,在系统中可有多个实例
- If an instance of the activity already exists at the top of the current task, the system routes the intent to that instance through a call to its
onNewIntent()
method, rather than creating a new instance of the activity. The activity can be instantiated multiple times, each instance can belong to different tasks, and one task can have multiple instances (but only if the activity at the top of the back stack is not an existing instance of the activity).For example, suppose a task's back stack consists of root activity A with activities B, C, and D on top (the stack is A-B-C-D; D is on top). 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 of D receives the intent throughonNewIntent()
, because it's at the top of the stack—the stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new instance of B is added to the stack, even if its launch mode is"singleTop"
.singleTop 可以保持只存在一个activity实例,但是是有要求的,就是这个activity必须在当前task的顶部!如果不在就会创建新的实例。应用场合如下:不想出现2个同样的activity在顶部。比如用户正在一个activity阅读信息,这时来了notification,用户点击后应该更新这些信息,而不是新建一个activity,这样在点击back时,就不会出现回到旧信息activity的情况了。这种情况正是下面这段英语提到的。
Note: When a new instance of an activity is created, the user can press the Back button to return to the previous activity. But when an existing instance of an activity handles a new intent, the user cannot press the Back button to return to the state of the activity before the new intent arrived in
onNewIntent()
. "singleTask" 在系统中保持唯一实例
- The system creates a new task and instantiates the activity at the root of the new task. However, if an instance of the activity already exists in a separate task, the system routes the intent to the existing instance through a call to its
onNewIntent()
method, rather than creating a new instance. Only one instance of the activity can exist at a time. - 有实例存在就跳转到该实例,没有实例存在就会创建新的task,并把实例放在root。这里需要注意的是,有实例存在的情况,如果这个实例不在task的顶端,那么不会自动把它置顶,参看下面的FLAG_ACTIVITY_NEW_TASK。
-
Note: Although the activity starts in a new task, the Back button still returns the user to the previous activity.
"singleInstance"
. 在系统中保持唯一实例,并且单独存在一个task中- Same as
"singleTask"
, except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task; any activities started by this one open in a separate task. - 关于这4种的区别,请参看http://developer.android.com/guide/topics/manifest/activity-element.html#clear如果你不喜欢英文,请参看http://blog.csdn.net/guomeijuan916/article/details/8121468
As another example, the Android Browser application declares that the web browser activity should always open in its own task—by specifying the singleTask
launch mode in the <activity>
element. This means that if your application issues an intent to open the Android Browser, its activity is not placed in the same task as your application. Instead, either a new task starts for the Browser or, if the Browser already has a task running in the background, that task is brought forward to handle the new intent.
Regardless of whether an activity starts in a new task or in the same task as the activity that started it, the Backbutton always takes the user to the previous activity. However, if you start an activity that specifies thesingleTask
launch mode, then if an instance of that activity exists in a background task, that whole task is brought to the foreground. At this point, the back stack now includes all activities from the task brought forward, at the top of the stack. Figure 4 illustrates this type of scenario.
注意,整个task都被移动到了前台,包括activity x! 不过activity x 和activity y的这个task是如何生成的呢?activity y作为singleTask类型,不是应该在task的root吗?为什么这里它不在root上呢?怎么做到的?如果activity x在上方又会怎么样?系统会自动把activity x弹出去舍弃吗?
Figure 4. A representation of how an activity with launch mode "singleTask" is added to the back stack. If the activity is already a part of a background task with its own back stack, then the entire back stack also comes forward, on top of the current task.
For more information about using launch modes in the manifest file, see the <activity>
element documentation, where the launchMode
attribute and the accepted values are discussed more.
Note: The behaviors that you specify for your activity with the launchMode
attribute can be overridden by flags included with the intent that start your activity, as discussed in the next section.
Using Intent flags
When starting an activity, you can modify the default association of an activity to its task by including flags in the intent that you deliver to startActivity()
. The flags you can use to modify the default behavior are:
FLAG_ACTIVITY_NEW_TASK
Start the activity in a new task. If a task is already running for the activity you are now starting, that task is brought to the foreground with its last state restored and the activity receives the new intent inonNewIntent()
.
This flag is generally used by activities that want to present a "launcher" style behavior: they give the user a list of separate things that can be done, which otherwise run completely independently of the activity launching them. When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in.
根据这里所说的,放到前台的是整个task,该activity会收到onNewIntent()信息,但是不会把这个activity放到task的顶端,如果需要同时现实该activity,那么应该和FLAG_ACTIVITY_CLEAR_TOP一起使用!
This produces the same behavior as the "singleTask"
launchMode
value, discussed in the previous section.
FLAG_ACTIVITY_SINGLE_TOP
If the activity being started is the current activity (at the top of the back stack), then the existing instance receives a call to onNewIntent()
, instead of creating a new instance of the activity.
This produces the same behavior as the "singleTop"
launchMode
value, discussed in the previous section.
FLAG_ACTIVITY_CLEAR_TOP
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent. For example, consider a task consisting of the activities: A, B, C, D. If D calls startActivity() with an Intent that resolves to the component of activity B, then C and D will be finished and B receive the given Intent, resulting in the stack now being: A, B. The currently running instance of activity B in the above example will either receive the new intent you are starting here in its onNewIntent() method, or be itself finished and restarted with the new intent. If it has declared its launch mode to be "multiple" (the default) and you have not set FLAG_ACTIVITY_SINGLE_TOP in the same intent, then it will be finished and re-created; for all other launch modes or if FLAG_ACTIVITY_SINGLE_TOP is set then this Intent will be delivered to the current instance's onNewIntent(). This launch mode can also be used to good effect in conjunction with FLAG_ACTIVITY_NEW_TASK: if used to start the root activity of a task, it will bring any currently running instance of that task to the foreground, and then clear it to its root state. This is especially useful, for example, when launching an activity from the notification manager.
注意上面说说的,clear_top这个标志位不一定会调用 onNewIntent(), 只有同时使用 FLAG_ACTIVITY_SINGLE_TOP,才会调用onNewIntent(),不然,会先finish本身,再创建一个新的!!
There is no value for the launchMode
attribute that produces this behavior.
FLAG_ACTIVITY_CLEAR_TOP
is most often used in conjunction with FLAG_ACTIVITY_NEW_TASK
. When used together, these flags are a way of locating an existing activity in another task and putting it in a position where it can respond to the intent.
Note: If the launch mode of the designated activity is "standard"
, it too is removed from the stack and a new instance is launched in its place to handle the incoming intent. That's because a new instance is always created for a new intent when the launch mode is "standard"
.
android:launchMode
An instruction on how the activity should be launched. There are four modes that work in conjunction with activity flags (FLAG_ACTIVITY_*
constants) in Intent
objects to determine what should happen when the activity is called upon to handle an intent. They are:
"standard
"
"singleTop
"
"singleTask
"
"singleInstance
"
The default mode is "standard
".
As shown in the table below, the modes fall into two main groups, with "standard
" and "singleTop
" activities on one side, and "singleTask
" and "singleInstance
" activities on the other. An activity with the "standard
" or "singleTop
" launch mode can be instantiated multiple times. The instances can belong to any task and can be located anywhere in the activity stack. Typically, they're launched into the task that called
(unless the Intent object contains astartActivity()
instruction, in which case a different task is chosen — see the taskAffinityattribute).FLAG_ACTIVITY_NEW_TASK
In contrast, "singleTask
" and "singleInstance
" activities can only begin a task. They are always at the root of the activity stack. Moreover, the device can hold only one instance of the activity at a time — only one such task.
The "standard
" and "singleTop
" modes differ from each other in just one respect: Every time there's a new intent for a "standard
" activity, a new instance of the class is created to respond to that intent. Each instance handles a single intent. Similarly, a new instance of a "singleTop
" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an
call); a new instance is not created. In other circumstances — for example, if an existing instance of the "onNewIntent()
singleTop
" activity is in the target task, but not at the top of the stack, or if it's at the top of a stack, but not in the target task — a new instance would be created and pushed on the stack.
The "singleTask
" and "singleInstance
" modes also differ from each other in only one respect: A "singleTask
" activity allows other activities to be part of its task. It's always at the root of its task, but other activities (necessarily "standard
" and "singleTop
" activities) can be launched into that task. A "singleInstance
" activity, on the other hand, permits no other activities to be part of its task. It's the only activity in the task. If it starts another activity, that activity is assigned to a different task — as if FLAG_ACTIVITY_NEW_TASK
was in the intent.
Use Cases | Launch Mode | Multiple Instances? | Comments |
---|---|---|---|
Normal launches for most activities | "standard " |
Yes | Default. The system always creates a new instance of the activity in the target task and routes the intent to it. |
"singleTop " |
Conditionally | If an instance of the activity already exists at the top of the target task, the system routes the intent to that instance through a call to itsonNewIntent() method, rather than creating a new instance of the activity. |
|
Specialized launches (not recommended for general use) |
"singleTask " |
No | The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to itsonNewIntent() method, rather than creating a new one. |
"singleInstance " |
No | Same as "singleTask" , except that the system doesn't launch any other activities into the task holding the instance. The activity is always the single and only member of its task. |
As shown in the table above, standard
is the default mode and is appropriate for most types of activities. SingleTop
is also a common and useful launch mode for many types of activities. The other modes — singleTask
and singleInstance
— are not appropriate for most applications, since they result in an interaction model that is likely to be unfamiliar to users and is very different from most other applications.
Regardless of the launch mode that you choose, make sure to test the usability of the activity during launch and when navigating back to it from other activities and tasks using the Back button.
Android 阅读Tasks and Back Stack文章后的重点摘抄的更多相关文章
- Activity启动模式 Tasks和Back Stack
http://www.cnblogs.com/mengdd/archive/2013/06/13/3134380.html Task是用户在进行某项工作时需要与之交互的一系列activities的集合 ...
- 简单的 Android 拍照并显示以及获取路径后上传
简单的 Android 拍照并显示以及获取路径后上传 Activity 中的代码,我只贴出重要的事件部分代码 public void doPhoto(View view) { destoryBimap ...
- [转]关于sdk更新Android SDK Tools 25.3.1版本后使用sdk manager闪退
昨天这两个manager还工作正常,今天更新了一下,发现不可用了,运行avd manager和sdk manager没反应,搜了好多文章,然后看到了下这篇文章<关于sdk更新Android SD ...
- 用python+selenium登录cnblog后新增文章后再次删除该文章
目的:登录cnblog后新增文章后再次删除该文章并验证 代码如下: #coding: utf-8 from selenium import webdriver from time import sle ...
- 粗略阅读《Agile Software Development》后的感想
大致配合翻译和词典阅读了一下这篇文章之后,我另外还查阅了维基百科.百度百科和MBA智库百科还有一些网络上的文章.对敏捷开发有了一个大致上的浅显的认识. 敏捷建模(Agile Modeling,AM)的 ...
- 解决Android Studio 3.0导入module依赖后unable to merge index
解决Android Studio 3.0导入module依赖后unable to merge index 项目需要使用im, 在项目里导入了腾讯im的几个module依赖, 项目无法编译, 报错una ...
- android studio 升级到3.3.1后,提示程序包不存在
android studio 升级到3.3.1后,提示程序包不存在 原因 主Module--A 引用了其他Moduel--B里的jar库, 只需要把B的dependencies改成如下(implent ...
- 转:关于Python中的lambda,这篇阅读量10万+的文章可能是你见过的最完整的讲解
lambda是Python编程语言中使用频率较高的一个关键字.那么,什么是lambda?它有哪些用法?网上的文章汗牛充栋,可是把这个讲透的文章却不多.这里,我们通过阅读各方资料,总结了关于Python ...
- Android 6.0 运行时权限处理完全解析 (摘抄)
转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/50709663: 本文出自:[张鸿洋的博客] 一.概述 随着Android 6. ...
随机推荐
- Maven 教程
Maven 教程 序:几次对Maven 的学习,都因为各种原因 而中途切断了,再一次学习的时候,又不得不重新开始,结果发现 又不记得步骤 又找不到对应的文档.别人写的再好,终究比不过自己亲手实践的得出 ...
- ssh整合常见的错误
1.报错信息:java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refres ...
- JAVA 中SQL字符动态拼接
select SYR,SFZMHM,CJRZH,XSZBH,HPHM,CLSBDH,FDJH,CLLX,ZDYZT,to_char(CCDJRQ,'YYYY-MM-DD') CCDJRQ from V ...
- linux内存回收 内核参数
ss -atu| awk '/^tcp/{++S[$2]} END {for(a in S) print a,S[a]}' ps up pid (RSS:实际内存大小,长驻内存) ps o pid,c ...
- 安装coreseek找不到mysql
1.安装 coreseek-3.2.14 遇到问题:“ERROR: cannot find MySQL include files,随即在网上搜索各种答案说是要找到mysql.h的正确路径加入./co ...
- Sencha Touch 2.2.1 Custom Icon 自定义图标
ST2.2版本竟然又改变了sass中自定义图标的添加方式,在2.2以前采用的是这种base64的方式,详见:http://www.cnblogs.com/qidian10/archive/2012/1 ...
- static NSString *ID的改进
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPa ...
- mybatis 使用resultMap实现数据库的操作
resultType:直接表示返回类型 resultMap:对外部resultMap的引用 二者不能同时使用 创建一个实体类Role和User public class Role { private ...
- ssh框架整合完整版
1.导入jar包 可以在src下添加一个log4j.properties文件来记录日志 2.加入实体类+映射文件 映射:从类入手class+属性 a.映射的头文件在:hibernate3.jar--& ...
- iOS: FFMpeg编译和使用问题总结
iOS: FFmpeg编译和使用问题总结 折磨了我近一周多时间的FFmpeg库编译问题终于解决了,必须得把这一段时间来遇到过的坑全写出来.如果急着解决问题,编译最新版本的FFmpeg库请直接看第二部分 ...