一个应用通常有多个Activity。每个activity围绕一个特定的功能设计,用户可以操作它并且可以启动其他的activity。举个例子,一个电子邮件应用可能有一个activity去呈现新邮件列表。当用户选择了一封邮件,会打开一个新的activity来呈现邮件内容。
一个activity可以启动另一个应用的activity。例如,如果你的应用想要发送email,你可以定义一个intent来执行一个发送操作并且携带一些数据:email的地址,消息。一个其他应用的activity需要声明可以处理这类的intent。在这个例子中,intent是要发送一封email,所以一个email应用会启动(如果有多个activity支持同一个intent,系统会让用户选择要使用哪一个)。当email被发送出去,你的activity会恢复,看起来,email
activity就是你应用的一部分。为维护这种无缝的用户体验,尽管activity可能来自于不同的应用,android系统依然会将这些activity都保存在同一个任务中。
一个任务就是用户为了执行特定工作而与之交互的activity的集合。这些activity会根据被打开的顺序被安放在一个栈(回退栈)中。
设备的主屏幕是大多数任务的启动场所。当用户触摸一个应用图标,该应用的任务就会来到前台。如果该应用当时没有任务,就会创建一个新任务,同时,主activity就会作为这个栈中的根activity被打开。
当一个activity启动另一个activity时,这个新的activity会被放到栈的顶端并且获得焦点。前一个activity仍然保存在栈中,但已经被停止了。当一个activity停止,系统会保存用户界面面的当前状态。当用户按了返回按钮,当前的activity会被弹出栈(activity会被销毁)并且恢复前一个activity(使用刚被保存的UI状态恢复)。在栈中的activity只有在弹出和压入两种操作--被当前activity启动时压入,用户使用返回按钮离开时弹出,除此之外,栈中activity位置和顺序都不会发生变化。正应为这样,回退栈的操作符合“后进先出”的原则。下面的图沿着时间线演示了回退栈在不同时刻的进度。
如果用户继续按返回,那么在栈中所有的activity都会被弹出,知道用户返回到主屏幕(或者到该任务开始的地方)。当所有的activity都从栈中移除后,任务就不复存在了。
任务是一个紧密结合的单元,当用户开始一向新任务或者回到主屏幕(通过主屏幕按钮)时,它会被移到后台。当任务进入后台,栈中所有的activity都会停止,但是任务的回退栈会保持原封不动--当任务被另一个任务取代时只会简单的失去焦点(如下图所示)。任务可以重回到前台,所以用户可以在哪“丢弃”在哪“捡起”它。举个例子,有三个activity在当前任务(任务A)的栈中--其中两个在当前activity的下面。这时,用户按下Home键回到主屏幕,然后启动了一个新的应用。当显示主屏幕时,任务A进入后台。当新应用启动时,系统未该应用启动了一个新任务(任务B)。当用户与该应用交互完毕之后,重新回到主界面并且选择任务A的应用。这时,任务A回到前台--栈中的三个activity都原封未动并且恢复在栈顶的activity。在这个时候,用户依然可以Home键返回主屏幕,选择任务B的应用图标来切换到任务B(也可以通过最近使用应用列表启动)。这就是android多任务的一个例子。
注:在后台可以同时存在多个任务。但是,如果用户在运行多个后台任务,系统可能会销毁后台activity来回收内存,导致activity的状态丢失。关于这方面内容后面小节讲述。
因为在回退栈中的activity从来不会被重排,如果你的应用允许用户从多个activity启动一个特定的activity,那么会新创建该activity的一个实例并且把它放到放到栈顶。因此,在你的应用中一个activity可能被实例化多次,如下图所示。因此,用户使用回退键返回,那么每个activity的实例会按照被打开的反向顺序被显示。但是,如果你不想把一个activity实例化多次,你可以修改这种行为。关于如何修改,我们稍后会在“任务管理”一节中讨论。
让我们来总结一下activity和任务的默认行为:
- 当Activity A启动Activity B,Activity A会停止,但是系统会保存Activity A的状态(例如滚动条位置,编辑框中的文字等)。如果在Activity B时,玩家按返回键,会使用保存的状态恢复Activity A。
- 当用户按下Home键离开一个任务,当前的Activity会被停止并且当前任务会进入后台。系统保存该任务中所有Activity的状态。如果用户通过启动图标再次启动该任务,该任务会回到前台并且恢复栈顶端的Activity。
- 如果用户按下回退键,当前的Activity会从栈中弹出并且销毁。栈中的前一个Activity被恢复。当一个Activity被销毁时,系统不会保存该Activity的状态。
- Activity会被实例化多次,即使是由其他任务启动的。