Activity的4种启动模式整理笔记

Activity 的4种启动模式整理笔记

在介绍Activity的启动模式之前,我们先理解一下任务栈,所谓任务栈,就是桌面应用启动时,系统会为应用分配一个Activity栈(Task),用来存放Activity实例,首先他也是一个栈,所以有栈的特性先进后出,其主要有两个操作,压栈和出栈,其所存放的Activity是不支持重新排序的,只能根据压栈和出栈的操作更改Activity的顺序。
在当前 Activity 启动另一个 Activity 时,新的 Activity 将被推送到任务栈顶部并获得焦点。上一个 Activity 仍保留在任务栈中,但会停止。当 Activity 停止时,系统会保留其界面的当前状态。当用户按返回按钮时,当前 Activity 会从任务栈顶部移除(该 Activity 销毁),上一个 Activity 会恢复(界面会恢复到上一个状态)。任务栈中的 Activity 永远不会重新排列,只会被送入和移除,在当前 Activity 启动时被送入任务栈,在用户使用返回按钮离开时从任务栈中移除。因此,返回任务栈按照“后进先出”的特性运作。
正常情况下,当一个Activity启动了另一个Activity的时候,新启动的Activity就会置于任务栈的顶端,并处于活动状态,而启动它的Activity虽然成功身退,但依然保留在任务栈中,处于停止状态,当用户按下返回键或者调用finish()方法时,系统会移除顶部Activity,让后面的Activity恢复活动状态。当然,世界不可能一直这么“和谐”,可以给Activity设置一些“特权”,来打破这种“和谐”的模式,这种特权,就是通过在AndroidManifest文件中的属性andorid:launchMode来设置或者通过Intent的flag来设置的,lunchMode有以下几种:

standard -> 标准模式/默认模式
当我们没有显式地在清单文件里面指定activity的launchMode属性的时候,这个Activity就会以”standard“模式启动。该模式的特点是每次调用startActivity方法启动的时候都是新建一个Activity实例,并把此实例推入当前任务栈的栈顶。所以同一个Activity class可能会存在多个实例。

singleTop -> 栈顶模式
该启动模式与“standard”类似,区别就是如果当前任务栈栈顶的Activity正好是要启动的Activity类的实例,那么不会再创建新的Activity实例,而是调用当前实例的onNewIntent方法,把新的Intent传递给Activity实例对象。

singleTask -> 任务栈模式
启用新的任务栈里启动此Activity,如果其他任务栈中已经存在此Activity类的实例,那么不再创建新的实例,调用当前实例的onNewIntent方法,把新的Intent传递给Activity实例对象。在已经存在此Activity类的实例的情况下,如果此实例不在任务栈的栈顶,那么任务栈会对栈内的Activity进行出栈操作,直至目标Activity类的实例位于栈顶。

singleInstance -> 单例任务栈模式
与 “singleTask” 相似,不同的是,此启动模式下,目标Activity所在的任务栈有且仅有该Activity实例,在这个模式下的 Activity 实 例所处的 task 中,只能有这个 activity 实例,不能有其他的实例。一旦该模式的 activity 的实例已经存在于某个栈中,任何应用在激活该 activity 时都会重用该栈中的实例,解决了多个 task 共享一个 activity。

核心的 Intent Flag
FLAG_ACTIVITY_CLEAR_TOP
设置该flag,当这个 Activity 已经在当前的 Task 中运行,不会重新启动这个Activity 的实例,而是将这个 Activity 上方的所有 Activity 都将关闭,然后这个 Intent 会作为 一个新的 Intent 投递到老的 Activity(现在位于顶端)中。

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
设置该flag,这将在 Task 的 Activity stack 中设置一个还原点,当 Task 恢复时,需要清理Activity。也就是说,下一次 Task 带着 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 标记进入前台时(典型的操作是用户在主画面重启它),这个 Activity 和它之上的都将关闭,以至于用户不能再返回到它们,但是可以回到之前的 Activity。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
设置该flag,新的 Activity 不会在最近启动的 Activity 的列表中保存。

FLAG_ACTIVITY_FORWARD_RESULT
设置该flag,并且这个 Intent 用于从一个存在的 Activity 启动一个新的 Activity,那么,这个作为答复目标的 Activity 将会传到这个新的 Activity 中。这种方式下,新的 Activity 可以调用 setResult(int),并且这个结果值将发送给那个作为答复目标的 Activity。

FLAG_ACTIVITY_MULTIPLE_TASK
一般情况不要使用这个标志,除非你自己实现了应用程序启动器。与 FLAG_ACTIVITY_NEW_TASK 结合起来使用,可以禁用把已存的 Task 送入前台的行为。当设置时,新的 Task 总是会启动来处理 Intent,而不管是否已经有一个 Task 可以处理相同的事情。由于默认的系统不包含图形 Task 管理功能,因此,不应该使用这个标志,除非你提供给用户一种方式可以返回到已经启动的 Task。如果 FLAG_ACTIVITY_NEW_TASK 标志没有设置,这个标志被忽略。

FLAG_ACTIVITY_NEW_TASK
设置该flag,这个 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_PREVIOUS_IS_TOP
如果设置,并且此Intent正用于从现有Activity启动新Activity,则当前在决定是否应该将新的Intent传递到顶层而不是开始一个新的Intent时,Activity不会被算作顶层Activity。前面的Activity将用作顶部,假设当前Activity将立即完成。

FLAG_ACTIVITY_REORDER_TO_FRONT
如果在 Intent 中设置,并传递给 Context.startActivity(),这个标志将引发已经运行的 Activity移动到历史 stack 的顶端。
例如,假设一个 Task 由四个 Activity 组成:A,B,C,D。如果 D 调用 startActivity()来启动 ActivityB ,那么, B 会移动到历史 stack 的顶端,现在的次序变成 A,C,D,B 。如果 FLAG_ACTIVITY_CLEAR_TOP 标志也设置的话,那么这个标志将被忽略。

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
如果设置,并且此Activity正在新Task中启动,或者正在将现有Task置于顶层,则它将作为Task的前门启动。这将导致应用使该Task处于正确状态所需的任何关联(将Activity移入或移出该Task),或者在需要时简单地将该Task重置为其初始状态。

FLAG_ACTIVITY_SINGLE_TOP
如果设置,当这个 Activity 位于历史 stack 的顶端运行时,不再启动一个新的。

注意:如果是从 BroadcastReceiver 启动一个新的 Activity,或者是从 Service 往一个 Activity 跳转时,不要忘记添加 Intent 的 Flag 为 FLAG_ACTIVITY_NEW_TASK。

Activity 的 4 种状态
活动

当一个 Activity 在栈顶,它是可视的、有焦点、可接受用户输入的。Android 试图尽最大可能保持它活动状态,杀死其它 Activity 来确保当前活动 Activity 有足够的资源可使用。 当另外一个 Activity 被激活,这个将会被暂停。

暂停
在很多情况下,你的 Activity 可视但是它没有焦点,换句话说它被暂停了。有可能原因是一个透明或者非全屏的 Activity 被激活。当被暂停,一个 Activity 仍会当成活动状态,只不过是不可以接受用户输入。在极特殊的情况下,Android 将会杀死一个暂停的 Activity 来为活动的 Activity 提供充足的资源。当一个 Activity 变为完全隐藏,它将会变成停止。

停止
当一个 Activity 不是可视的,它“停止”了。这个 Activity 将仍然在内存中保存它所 有的状态和会员信息。尽管如此,当其它地方需要内存时,它将是最有可能被释放资源的。 当一个 Activity 停止后,一个很重要的步骤是要保存数据和当前 UI 状态。一旦一个 Activity 退出或关闭了,它将变为待用状态。

待用
在一个 Activity 被杀死后和被装在前,它是待用状态的。待用 Acitivity 被移除 Activity 栈,并且需要在显示和可用之前重新启动它。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路上的码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值