Activity的生命周期已经了解了,那么Activity是怎么运做的呢? android
Activity栈:(Task) app
每一个Activity的状态是由它在Activity栈(是一个后进先出LIFO,包含全部正在运行Activity的队列)中的位置决定的。 动画
当一个新的Activity启动时,当前的活动的Activity将会移到Activity栈的顶部。 this
若是用户使用后退按钮返回的话,或者前台的Activity结束,在栈上的Activity将会移上来并变为活动状态。 spa
一个应用程序的优先级是受最高优先级的Activity影响的。当决定某个应用程序是否要终结去释放资源,Android内存管理使用栈来决定基于Activity的应用程序的优先级。 xml
Activity的4种状态: 生命周期
活动的:当一个Activity在栈顶,它是可视的、有焦点、可接受用户输入的。Android试图尽最大可能保持它活动状态,杀死其它Activity来确保当前活动Activity有足够的资源可以使用。当另一个Activity被激活,这个将会被暂停。 队列
暂停:在不少状况下,你的Activity可视可是它没有焦点,换句话说它被暂停了。有可能缘由是一个透明或者非全屏的Activity被激活。 事件
当被暂停,一个Activity仍会当成活动状态,只不过是不能够接受用户输入。在极特殊的状况下,Android将会杀死一个暂停的Activity来为活动的Activity提供充足的资源。当一个Activity变为彻底隐藏,它将会变成中止。 图片
中止:当一个Activity不是可视的,它“中止”了。这个Activity将仍然在内存中保存它全部的状态和会员信息。尽管如此,当其它地方须要内存时,它将是最有可能被释放资源的。当一个Activity中止后,一个很重要的步骤是要保存数据和当前UI状态。一旦一个Activity退出或关闭了,它将变为待用状态。
待用: 在一个Activity被杀死后和被装在前,它是待用状态的。待用Acitivity被移除Activity栈,而且须要在显示和可用以前从新启动它。
Activity的4种加载模式:
在android的多activity开发中,activity之间的跳转可能须要有多种方式,有时是普通的生成一个新实例,有时但愿跳转到原来某个activity实例,而不是生成大量的重复的activity。加载模式即是决定以哪一种方式启动一个跳转到原来某个Activity实例。
在android里,有4种activity的启动模式,分别为:
standard: 标准模式,一调用startActivity()方法就会产生一个新的实例。
singleTop: 若是已经有一个实例位于Activity栈的顶部时,就不产生新的实例,而只是调用Activity中的newInstance()方法。若是不位于栈顶,会产生一个新的实例。
singleTask: 会在一个新的task中产生这个实例,之后每次调用都会使用这个,不会去产生新的实例了。
singleInstance: 这个跟singleTask基本上是同样,只有一个区别:在这个模式下的Activity实例所处的task中,只能有这个activity实例,不能有其余的实例。
这些启动模式能够在功能清单文件AndroidManifest.xml中进行设置,中的launchMode属性。
若是是从BroadcastReceiver启动一个新的Activity,或者是从Service往Activity跳转时,要将Intent的Flag设置为FLAG_ACTIVITY_NEW_TASK才能够
影响加载模式的一些特性:
核心的Intent Flag有:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP
核心的特性有:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch
Activity在Activity栈(Task)中的加载顺序是能够控制的,这就须要用到Intent Flag
Intent经常使用标识:
FLAG_ACTIVITY_BROUGHT_TO_FRONT
这个标志通常不是由程序代码设置的,如在launchMode中设置singleTask模式时系统帮你设定。
FLAG_ACTIVITY_CLEAR_TOP
若是设置,而且这个Activity已经在当前的Task中运行,所以,再也不是从新启动一个这个Activity的实例,而是在这个Activity上方的全部Activity都将关闭,而后这个Intent会做为一个新的Intent投递到老的Activity(如今位于顶端)中。
例如,假设一个Task中包含这些Activity:A,B,C,D。若是D调用了startActivity(),而且包含一个指向Activity B的Intent,那么,C和D都将结束,而后B接收到这个Intent,所以,目前stack的情况是:A,B。
上例中正在运行的Activity B既能够在onNewIntent()中接收到这个新的Intent,也能够把本身关闭而后从新启动来接收这个Intent。若是它的启动模式声明为 “multiple”(默认值),而且你没有在这个Intent中设置FLAG_ACTIVITY_SINGLE_TOP标志,那么它将关闭而后从新建立;对于其它的启动模式,或者在这个Intent中设置FLAG_ACTIVITY_SINGLE_TOP标志,都将把这个Intent投递到当前这个实例的onNewIntent()中。
这个启动模式还能够与FLAG_ACTIVITY_NEW_TASK结合起来使用:用于启动一个Task中的根Activity,它会把那个Task中任何运行的实例带入前台,而后清除它直到根Activity。这很是有用,例如,当从Notification Manager处启动一个Activity。
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
若是设置,这将在Task的Activity stack中设置一个还原点,当Task恢复时,须要清理Activity。也就是说,下一次Task带着 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标记进入前台时(典型的操做是用户在主画面重启它),这个Activity和它之上的都将关闭,以致于用户不能再返回到它们,可是能够回到以前的Activity。
这在你的程序有分割点的时候颇有用。例如,一个e-mail应用程序可能有一个操做是查看一个附件,须要启动图片浏览Activity来显示。这个 Activity应该做为e-mail应用程序Task的一部分,由于这是用户在这个Task中触发的操做。然而,当用户离开这个Task,而后从主画面选择e-mail app,咱们可能但愿回到查看的会话中,但不是查看图片附件,由于这让人困惑。经过在启动图片浏览时设定这个标志,浏览及其它启动的Activity在下次用户返回到mail程序时都将所有清除。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
若是设置,新的Activity不会在最近启动的Activity的列表中保存。
FLAG_ACTIVITY_FORWARD_RESULT
若是设置,而且这个Intent用于从一个存在的Activity启动一个新的Activity,那么,这个做为答复目标的Activity将会传到这个新的Activity中。这种方式下,新的Activity能够调用setResult(int),而且这个结果值将发送给那个做为答复目标的 Activity。
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
这个标志通常不禁应用程序代码设置,若是这个Activity是从历史记录里启动的(常按HOME键),那么,系统会帮你设定。
FLAG_ACTIVITY_MULTIPLE_TASK
不要使用这个标志,除非你本身实现了应用程序启动器。与FLAG_ACTIVITY_NEW_TASK结合起来使用,能够禁用把已存的Task送入前台的行为。当设置时,新的Task老是会启动来处理Intent,而无论这是是否已经有一个Task能够处理相同的事情。
因为默认的系统不包含图形Task管理功能,所以,你不该该使用这个标志,除非你提供给用户一种方式能够返回到已经启动的Task。
若是FLAG_ACTIVITY_NEW_TASK标志没有设置,这个标志被忽略。
FLAG_ACTIVITY_NEW_TASK
若是设置,这个Activity会成为历史stack中一个新Task的开始。一个Task(从启动它的Activity到下一个Task中的 Activity)定义了用户能够迁移的Activity原子组。Task能够移动到前台和后台;在某个特定Task中的全部Activity老是保持相同的次序。
这个标志通常用于呈现“启动”类型的行为:它们提供用户一系列能够单独完成的事情,与启动它们的Activity彻底无关。
使用这个标志,若是正在启动的Activity的Task已经在运行的话,那么,新的Activity将不会启动;代替的,当前Task会简单的移入前台。参考FLAG_ACTIVITY_MULTIPLE_TASK标志,能够禁用这一行为。
这个标志不能用于调用方对已经启动的Activity请求结果。
FLAG_ACTIVITY_NO_ANIMATION
若是在Intent中设置,并传递给Context.startActivity()的话,这个标志将阻止系统进入下一个Activity时应用 Acitivity迁移动画。这并不意味着动画将永不运行——若是另外一个Activity在启动显示以前,没有指定这个标志,那么,动画将被应用。这个标志能够很好的用于执行一连串的操做,而动画被看做是更高一级的事件的驱动。
FLAG_ACTIVITY_NO_HISTORY
若是设置,新的Activity将再也不历史stack中保留。用户一离开它,这个Activity就关闭了。这也能够经过设置noHistory特性。
FLAG_ACTIVITY_NO_USER_ACTION
若是设置,做为新启动的Activity进入前台时,这个标志将在Activity暂停以前阻止从最前方的Activity回调的onUserLeaveHint()。
典型的,一个Activity能够依赖这个回调指明显式的用户动做引发的Activity移出后台。这个回调在Activity的生命周期中标记一个合适的点,并关闭一些Notification。
若是一个Activity经过非用户驱动的事件,如来电或闹钟,启动的,这个标志也应该传递给Context.startActivity,保证暂停的Activity不认为用户已经知晓其Notification。
FLAG_ACTIVITY_PREVIOUS_IS_TOP
If set and this intent is being used to launch a new activity from an existing one, the current activity will not be counted as the top activity for deciding whether the new intent should be delivered to the top instead of starting a new one. The previous activity will be used as the top, with the assumption being that the current activity will finish itself immediately.
FLAG_ACTIVITY_REORDER_TO_FRONT
若是在Intent中设置,并传递给Context.startActivity(),这个标志将引起已经运行的Activity移动到历史stack的顶端。
例如,假设一个Task由四个Activity组成:A,B,C,D。若是D调用startActivity()来启动Activity B,那么,B会移动到历史stack的顶端,如今的次序变成A,C,D,B。若是FLAG_ACTIVITY_CLEAR_TOP标志也设置的话,那么这个标志将被忽略。
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
If set, and this activity is either being started in a new task or bringing to the top an existing task, then it will be launched as the front door of the task. This will result in the application of any affinities needed to have that task in the proper state (either moving activities to or from it), or simply resetting that task to its initial state if needed.
FLAG_ACTIVITY_SINGLE_TOP
若是设置,当这个Activity位于历史stack的顶端运行时,再也不启动一个新的。
注意:若是是从BroadcastReceiver启动一个新的Activity,或者是从Service往一个Activity跳转时,不要忘记添加Intent的Flag为FLAG_ACTIVITY_NEW_TASK。