一个Activity允许用户完成一些操作,甚至,Android中设计Activity为组件的形式,这样,多个Activity——甚至是其它App的Activity可以一起完成一项任务。
多个Activity一起完成一项工作时,它们的集合被称作一个Task。 A task is a collection of activities that users interact with when performing a certain job.
一个Task所有的Activity被放置在一个stack结构
中,根据它们的启动顺序被添加。
stack不会进行重新排列,只会在打开新Activity时添加其到栈顶,或finish时从栈顶移除。所以Activity在此stack中表现为"last in, first out"。
因为上述特点,多个Activity在打开和关闭时,stack表现出“回退栈”这样的效果。
系统中,每一个Activity组件实例被使用一个ActivityRecord对像表示,所有的Activity组件都保存在一个ActivityStack对象的字段ArrayList mHistory中。 ActivityRecord.task字段表示其所在Task,类型是TaskRecord。 假设把所有Activities指定编号:a0,a1,a2...an,表示mHistory中第0,1,2...n个Activity,那么,Task就是从a0到an中连续的一个个“子序列”,一个Task包括1或多个Activity。 可见:Task中的Activity的“栈结构”是通过ArrayList间接实现的。
在启动一个Activity时,可以在Intent中添加标记,指示其运行在新的Task中,还是已经存在的Task中。
若为Activity指定为NEW_TASK,那么它被添加到mHistory的末尾,并且作为新Task的栈底的Activity—— root activity。
若启动的Activity运行在已有的Task中,此时: 对mHistory进行倒序遍历,找到task和对应newActivity一致的ActivityRecord record对像,然后添加其到此record后面。
当一个Activity中栈顶Activity正在显示时,它就是前台Task。 栈顶topActivity转为stopped状态时Task也变为后台的。 一个Activity总是属于某个Task,它的Resumed或Stopped状态影响其Task状态。
每次Task栈顶的Activity被finish,那么它出栈。新的栈顶的Activity被resume。 若所有Activity都finish并出栈,此Task不再存在,之前启动此Task时的前台Task被转到前台。
Activity和Task默认的表现是:
处于stopped状态的Activity,它的内存状态和Resumed比并没有变化。这样稍后用户回到界面时可以从Stopped状态转为Resumed状态,即从后台转到前台。
不过系统为了内存利用,可能回收长期处于后台的Activity,这样,
用户再回到界面时,Activity会重新创建,未保存的状态会丢失。
为了之后用户回到当前Task时继续原先的操作,需要主动保存view和activity对象的一些状态。
通过:
onSaveInstanceState(Bundle outState)
onRestoreInstanceState(Bundle savedInstanceState)
onCreate(Bundle savedInstanceState)
可以通过manifest文件中配置
attribute有:
taskAffinity launchMode allowTaskReparenting clearTaskOnLaunch alwaysRetainTaskState finishOnTaskLaunch
flag有:
FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_SINGLE_TOP
可以通过配置
使用launchMode
attribute。
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.
如果当前Task栈顶是对应Activity类的实例,则将intent传递给它的onNewIntent()方法,不创建新实例。
特点:一个Task中可以存在多个,多个实例可以存在于不同Task中。
若当前Task或其它Task中存在要启动的Activity的实例,就发送intent给它,并且设置了flag:Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT。已有的Activity的onNewIntent()被执行,位于其上的stack中的其它Activity都会被finish,只留下此rootActivity被resume。
若系统中还不存在Activity实例,就创建一个新Task,并且将此Activity作为其root activity。此时,若finish此实例,将回到启动它时的前一个Activity。
特点:只能有一个。
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.
特点:只能有一个,且其Task只包含此Activity。
不论启动的Activity在当前Task还是新的Task中,返回按钮总是把用户带到前一个Activity界面。
若启动singleTask的Activity在其它Task2中,那么其中的Activity都会被添加到当前Task的返回路径的前面,所以仅在用户关闭对应Task2中的所有Activity后,才返回到当前启动操作时的Task1。
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.
和 "singleTask" 的行为一样。
和"singleTop"一样。
If the activity being started 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 are destroyed and this intent is delivered to the resumed instance of the activity (now on top), through onNewIntent()).
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".
官方文档乱写?
The affinity indicates which task an activity prefers to belong to.
默认的每个activity的affinity是其包名。
可以使用android:taskAffinity
改变application或某个activity的taskAffinity。
使用taskAffinity用途一般是:
默认情况下,系统会保持Task中的stack,即便对应Activity的进程被回收,它还会重建。 若较长时间再回到当前Task,系统会选择清除root外的所有Activity。
可以通过对Activity设置标签属性定制行为:
入口Activity所在的Task一般认为是application的main Task。 当app启动后,点击桌面的icon可以在任何时候返回到main Task。