一个应用程序通常包含多个活动。每个活动应围绕行动的用户可以执行,并且可以启动其他活动的特定种类进行设计。例如,电子邮件应用程序可能具有一个活动,以显示新的消息的列表。当用户选择一个信息,一个新的活动打开,以查看该消息。
的活性甚至可以就存在于设备上的其他应用程序的活动。例如,如果你的应用程序想要发送电子邮件时,您可以定义执行“发送”采取行动的意图,包括一些数据,如电子邮件地址和消息。从声明本身来处理这种意图的其他应用程序的活动,然后打开。在这种情况下,目的是发送电子邮件,所以电子邮件应用程序“撰写”活动启动(如果有多个活动支持相同的意图,然后系统让用户选择使用哪一个)。当发送的电子邮件,你的活动,并恢复它好像电子邮件活动是应用程序的一部分。虽然活动可能来自不同的应用程序,Android的维护通过保持在相同的任务活动都这种无缝的用户体验。
任务是用户执行某些任务时,互动活动的集合。活动都布置成堆叠(背面叠层),在其中,每个活动被打开的顺序。
该设备主屏幕是大多数任务的起始位置。当用户触摸应用程序启动器的图标(或主屏幕上的快捷方式),该应用程序的任务来到前台。如果没有任务存在该应用程序(该应用程序尚未最近使用),则新的任务,创建与该应用程序的“主”活动打开,如在堆栈中的根活动。
当电流活动开始另一个新的活动推到堆栈的顶部和获得焦点。在先前的活动保持在栈,但已停止。当一个活动停止时,系统保持其用户接口的当前状态。当用户按下返回按钮,当前的活动,从堆栈的顶部弹出(活性被破坏)和前一活动恢复(其UI的先前状态被恢复)。在堆栈中的活动永远不会重新排列,只推和弹出堆栈推时,由当前的活动开始,当用户离开它使用后退按钮弹出到堆栈中。因此,回堆栈操作为“后进先出”的对象结构。图1可视化与示出具有在每个时间点的电流背面叠层沿活动之间的进度时间表此行为。
图1.在任务每一个新的活动是如何增加一个项目后面堆栈的表示。当用户按下后退按钮,当前的活动被破坏,以前的活动恢复。
如果用户继续按下后退,则在栈每个活动被弹出以显示前一个,直到用户返回到主屏幕(或取其活性运行时,任务开始)。当所有的活动都从堆栈中移除,任务不再存在。
图2.两个任务:任务B接收在前台用户交互,而任务A是在后台,等待被恢复。
图3.单一活动多次实例化。
任务是可以移动的“后台”,当用户开始一个新的任务或进入主屏幕,通过Home键一个有凝聚力的单位。而在后台,在任务中的所有活动都停止了,但该任务的堆栈背面保持不变,任务已经根本失去焦点,而另一个任务发生,如图2。然后一个任务可以返回“前台“,使用户可以拿起他们离开。假设,例如,当前的任务(任务A)具有在其堆栈个当前活动在三个活动。用户按下Home键,然后开始从应用程序启动一个新的应用程序。当出现在主屏幕上,任务A进入后台。当新的应用程序启动时,在系统启动该应用程序(任务B)和其自身的活动堆栈的任务。与该应用程序交互之后,用户再次返回家并且选择最初启动任务A.现在,应用程序,任务A来在其堆栈中的前景,所有三个活动完整并于堆栈恢复的顶部的活性。在这一点上,用户还可以回家和选择开始该任务的应用程序图标(或从总览画面中选择应用程序的任务)切换到任务B。这是多任务Android上的一个例子。
注:多重任务可以在后台同时举行。然而,如果用户在同一时间运行多个后台任务,系统可能会开始,以便破坏后台活动来恢复存储器,导致丢失的活动状态。请参阅有关的活动状态下节。
因为在后面堆栈中的活动永远不会重新排列,如果你的应用程序允许用户从多个活动启动一个特别的活动,是创建活动的新实例,并压入堆栈(而不是使活动的任何一个实例顶端)。这样,在应用程序中一个活动可能被多次实例化(即使从不同的任务),如图3这样,如果用户使用Back按钮导航向后,活动的每个实例揭示的顺序被打开(每一个都有自己的UI状态)。但是,您可以修改此行为,如果你不希望一个活动被实例化不止一次做。如何做到这一点在大约管理任务后面的章节中讨论。
总结各种活动和任务的默认行为:
当活动A开始活动B,活动A被停止,但系统保持其状态(如滚动位置并输入到表单文本)。如果用户按下返回键,而在活动B,活动A恢复其状态的恢复。
当用户通过按压主页按钮离开的任务,当前活动停止,它的任务进入后台。系统保留在任务的每一次活动的状态。如果用户稍后通过选择开始该任务的启动器图标恢复的任务,任务涉及到前景和在堆栈的顶部恢复活性。
如果用户按下后退按钮,当前的活动是从堆栈中弹出并销毁。在堆栈上一个活动重新开始。当一个活动被破坏,系统不会保留该活动的状态。
活动可以被实例化多次,即使从其他任务。
导航设计
欲了解更多有关应用程序的导航是如何工作的,在Android上阅读Android设计的导航指南。
节能活动状态
如上所讨论的,当它被停止系统的默认行为保留的活性的状态。这样,当用户导航回到以前的活动,它的用户界面出现在他们离开的方式。但是,您可以和应该-主动保留使用回调方法你的活动状态,以防活动被破坏,必须重新创建。
当系统停止的活动之一(当一个新的活动开始或任务移动到背景,如),系统可能是否需要恢复系统内存完全破坏该活性。发生这种情况时,关于该活动状态的信息丢失。如果发生这种情况,则系统仍然知道该活动在背面叠层一个地方,但是,当活动被带到堆栈的顶部,系统必须重新创建(而不是恢复它)。为了避免丢失用户的工作,你应该主动通过实现您的活动的onSaveInstanceState的()回调方法保留。
有关如何保存你的活动状态的更多信息,请参见活动文档。
管理任务
在Android的方式管理为相同的任务,并在上面所描述将所有活动正式开始纷纷“后进先出”的任务,并返回堆叠,堆叠的伟大工程,对于大多数应用程序,你不应该担心关于你的活动是如何与任务或如何相关,他们在后面堆栈存在。然而,你可能会决定要中断正常的行为。也许你想在你的应用的活动启动时(而不是放在当前的任务范围内),开始一个新的任务;或者,当你开始一个活动,你要提出它的一个现有实例(而不是在后面堆栈的顶部创建一个新的实例);或者,你希望你的背部栈的所有活动,除了当用户离开任务根系活力被清除。
你可以做这些事情多了,用在<活动>清单元素,并与意图标志的属性,你传递给startActivity()。
在这方面,主要的<活动>属性,你可以使用如下:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch
您还可以使用的主要意图标志是:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
在下面的章节中,您将看到如何使用这些清单属性和意图的标志来定义的活动是如何与任务,以及他们如何在后面堆栈的行为有关。
此外,单独讨论是任务和活动费如何可以表示和总览画面中管理的考虑。参见概述屏幕以获取更多信息。通常情况下,你应该让系统定义如何你的任务和活动总览画面中的代表,而你不需要修改此行为。
注意:大多数应用程序不应中断活动和任务的默认行为。如果确定有必要为您的活动来修改默认行为,谨慎使用并确保发射期间,测试活动的可用性以及其他活动和任务的后退按钮导航回到它的时候。一定要测试,可能与用户的预期行为相冲突的行为导航。
定义启动模式
启动模式允许您定义一个活动的新实例与当前任务相关联。您可以通过两种方式定义不同的启动模式:
使用清单文件
当您在清单文件中声明的活动,您可以指定活动应当与任务启动时关联。
使用意向的标志
当你调用startActivity(),您可以包括在Intent一个标志,宣告新的活动应该如何或者是否与当前任务相关联。
因此,如果活动A开始活动B,活动B可以在其清单定义应该如何与当前任务相关联(如果有的话)和活动A还可以要求活动B应该如何与当前任务相关联。如果这两个活动定义活动B应该如何与任务关联起来,那么活动A的请求(如意图定义)很荣幸在活动B的请求(在其清单中定义)。
注:可用于清单文件的一些启动模式不能作为标志的意图,同样,对于一个意图可以作为标志的一些启动模式不能在清单中定义。
使用清单文件
当声明清单档案中的一个活动,您可以指定活动应如何使用<活动>元素的launchMode属性的任务关联。
该launchMode属性指定的活动应该如何启动到任务的指令。有四个可以分配到launchMode属性不同的启动模式:
"standard"(默认方式)
默认。系统创建从它被启动,并且路由意图它在任务的活动的新实例。该活动可以被实例化多次,每个实例可以属于不同的任务,一个任务可以具有多个实例。
“singleTop”
如果活动的一个实例已存在于当前任务的顶部,系统路由通过其onNewIntent()方法的调用,而不是创建活动的新实例的意图,该实例。该活动可以被实例化多次,每个实例可以属于不同的任务,和一个任务可以有多个实例(但只有当在后面堆栈的顶部的活性是不活动的现有实例)。
例如,假定任务的回堆栈由与活动B,C和D在上面根系活力A的(堆栈A-B-C-D,D为顶部)。意向到达类型D的活性。如果D有默认的“标准”的推出模式,类推出的一个新实例,且堆栈成为A-B-C-D-D。然而,如果D的发射模式是“singleTop”,D的现有实例接收通过onNewIntent()的意图,因为它是在堆叠的堆叠的顶部保持的A-B-C-D。但是,如果意图到达用于B型的活性,则B的一个新实例被添加到堆栈中,即使它的发射模式是“singleTop”。
注意:当创建活动的新情况下,用户可以按后退按钮返回到以前的活动。但是,当一个活动的现有实例处理新的意图,用户不能按后退按钮返回到活动状态的新意图,onNewIntent到来之前()。
“singleTask”
系统将创建一个新的任务和新任务的根实例化的活动。然而,如果活动的实例中已存在一个单独的任务,该系统路由通过其onNewIntent()方法的调用,而不是创建一个新的实例意图的现有实例。仅在活动中的一个实例可以在一个时间存在。
注意:虽然活动在一个新的任务开始,后退按钮仍然使用户返回到先前的活动。
“singleInstance”。
同为“singleTask”,所不同的是,系统不发射任何其他的活动进保持该实例的任务。活动始终是它的任务单,唯一的成员;任何活动,通过这一个在一个单独的任务开放开始。
另一个例子是,Android浏览器应用程序声明的Web浏览器的活动要经常在自己的任务,通过指定<活动>元素singleTask启动模式打开。这意味着,如果你的应用程序发出的意图打开Android浏览器,它的活动不放在同一个任务,您的应用程序。相反,无论是新的任务 - 为浏览器启动时,或者,如果浏览器已经在后台运行一个任务,该任务被提出来处理新的意图。
不管活动是否在一个新的任务或在同一任务,启动它的活动开始,后退按钮始终把用户以前的活动。但是,如果你开始指定singleTask启动模式的活动,则该活动的一个实例,在后台任务存在,那整个任务带到前台。在这一点上,回栈现在包括从任务的所有活动提出,在堆栈的顶部。图4显示了这种类型的场景。
图4与发射模式“singleTask”的活性如何被添加到回栈的表示。如果活动是已与它自己的背面叠层后台任务的一部分,则整个背面叠层还附带向前,在当前任务的顶部。
有关在manifest文件中使用发射模式的详细信息,请参阅<活动>元素的文档,其中launchMode属性和接受的价值进行了讨论更多。
注意:您指定的launchMode属性的活动的行为,可以通过包括与启动活动的意图标志覆盖,如在下一节讨论。
使用意向的标志
当启动一个活动,你可以通过在意图的标志,你传递给startActivity()修改活动,其任务的默认关联。你可以用它来修改默认行为的标志是:
FLAG_ACTIVITY_NEW_TASK
在开始新任务的活动。如果任务已经为你现在也开始活动运行状态,确保任务带到前台,其最后的状态恢复,并在活动中收到的onNewIntent新意图()。
这会产生相同的行为“singleTask”launchMode值,前一节中讨论。
FLAG_ACTIVITY_SINGLE_TOP
如果被启动的活性是当前活动(在后面堆栈的顶部),则现有的实例接收而不是创建活动的新实例)调用onNewIntent(,。
这产生相同的行为为“singleTop”launchMode值,前一节中讨论。
FLAG_ACTIVITY_CLEAR_TOP
如果正在启动的活动在目前的任务已经在运行,那么代替开展这一活动的新实例,都在它之上的其他活动中被破坏,这个意图传递到恢复活动的实例(今顶),通过onNewIntent())。
没有为产生这种行为的launchMode属性没有价值。
FLAG_ACTIVITY_CLEAR_TOP最常与FLAG_ACTIVITY_NEW_TASK一起使用。当一起使用时,这些标志是定位在另一个任务现有活动,并把它在一个位置,它可以给意向响应的一种方式。
注意:如果指定的活动的启动模式为“标准”,它也是从堆栈中移除一个新的实例在其位来处理传入的意图启动。这是因为一个新的实例为何时推出模式为“标准”的新意图始终创建。
处理亲和力
亲和指示活动更喜欢哪个任务属于。默认情况下,都来自同一个应用程序的活动,对彼此的亲和力。这样,默认,在同一应用程序的所有活动倾向于在相同的任务。但是,您可以修改活动的默认亲和力。在相同的应用程序定义不同的应用中定义可以共享具有亲和性的活动,或活动可以被分配不同的任务的亲和力。
您可以修改亲和力与<活动>元素的属性taskAffinity任何给定的活动。
该taskAffinity属性需要一个字符串值,它必须从<清单>元素中声明默认的包名唯一的,因为该系统将使用该名称来标识应用程序的默认任务亲和力。
亲和进场在两种情况下:
当启动一个活动意图包含FLAG_ACTIVITY_NEW_TASK标志。
一个新的活动,在默认情况下,射入调用startActivity()活动的任务。它推到相同的回栈调用者。但是,如果传递给startActivity()的意图包含FLAG_ACTIVITY_NEW_TASK标志,系统会寻找不同的任务,以容纳新的活动。通常情况下,这是一个新的课题。然而,这并不必须如此。如果已经有一个与作为新的活动相同的亲和力现有任务,活动发射到该任务。如果不是,它开始一个新的任务。
如果这个标志导致活动开始一个新的任务,用户按下Home键离开它,必须有某种方式为用户导航回任务。一些实体(如通知管理器)总是一个外部任务开始的活动,从来没有像自己的一部分,所以他们总是把FLAG_ACTIVITY_NEW_TASK在他们通过给startActivity的意图()。如果你有一个可以通过可能使用此标志的外部实体调用的活动,采取用户有独立的方式回到那个年代开始,如用发射器图标(任务的根系活力的任务护理有CATEGORY_LAUNCHER意图过滤器;请参阅下面的启动任务部分)。
当一个活动都有其allowTaskReparenting属性设置为“真”。
在这种情况下,活动可以从它开始它具有亲和性的任务的任务移动,当该任务涉及到前台。
例如,假设该报告的天气条件中选择的城市的活性被定义为一个旅游应用程序的一部分。它具有如在同一应用程序的其他活动相同的亲和力(默认的应用程序亲和力),它允许重新养育具有此属性。当你的活动中的一个开始,天气报告基因活性,它最初属于相同的任务中的活动。然而,当旅行应用程序的任务涉及到前台,天气报告活性被重新分配到该任务,并在其内显示。
提示:如果一个.apk文件包含但从用户的角度不止一个“应用程序”,你可能想使用taskAffinity属性分配不同的亲和力与每一个“应用程序”相关的活动。
清除栈回
如果用户离开了很长时间的任务,系统清除除了根活性的所有活动的任务。当用户再次返回到任务,只有根活性恢复。该系统的行为这种方式,因为,延长的时间量之后,用户可能已经放弃了他们之前被做的和正在返回的任务,开始新的东西。
有一些活动属性,你可以用它来修改此行为:
alwaysRetainTaskState
如果这个属性在任务的根系活力设置为“true”,刚刚描述的默认行为不会发生。该任务即使经过长时间保留在堆栈中的所有活动。
clearTaskOnLaunch
如果这个属性在任务的根系活力设置为“真”,堆栈被清除下来,每当用户离开任务并返回到它的根系活力。换句话说,它是alwaysRetainTaskState相反。用户总是返回到它的初始状态的任务时,离去的任务只有一个的时刻,即使之后。
finishOnTaskLaunch
该属性是像clearTaskOnLaunch,但它运行在一个单一的活动,而不是一个完整的任务。它还可能导致的任何活动走开,包括根系活力。当它被设置为“真”,该活动仍然只对当前会话的任务的一部分。如果用户离开,然后返回到该任务,这是不再存在。
启动任务
您可以通过给它一个意图过滤器一个带有“android.intent.action.MAIN”为指定的操作和“android.intent.category.LAUNCHER”为指定的类别设置一个活动为切入点的任务。例如:
<
<activity ... >
<intent-filter ... >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
...
</activity>
这样的一个意图过滤器会导致要显示在应用程序启动的活动,给用户的方式来开展活动,并返回到它创建它已经启动之后的任何时间任务的图标和标签。
这第二个能力是很重要的:用户必须能够留下一个任务,然后回来以后再使用这个活动发射器。出于这个原因,该标活动总是启动一个任务,“singleTask”和“singleInstance”两个发射模式,应该使用只有当活动具有ACTION_MAIN和CATEGORY_LAUNCHER滤波器。想象一下,例如,如果过滤器丢失会发生什么:一个意图启动一个“singleTask”活动,启动了新的任务,用户花费一些时间完成这项任务的工作。然后,用户按下Home键。任务现在发送给背景和不可见。现在,用户没有办法返回任务,因为它不是在应用程序启动来表示。
对于那些情况下,你不希望用户能够回到一个活动,设置<活动>元素的finishOnTaskLaunch为“true”(请参阅清除栈)。
关于任务和活动费如何表示和管理概览屏幕方面进一步的资料概述屏幕可用。