Android 任务栈空间,【Android】任务和返回栈(tasks and back stack)

2023-05-16

tasks and back stack

一个Task就是一组activity的集合。这些activity按照它们打开的顺序被放置于一个先进后出的栈中(back stack)。

用户点击图标打开一个app时,该app的task会被移到前台显示。如果当前没有该app的task,系统将会新建一个task并在其中运行Main activity。

一个activity(A)打开另一个activity(B),B将会被置于栈顶并显示,A仍然处于栈中,系统会保存它的状态。 如果按下返回键,当前的activity将被弹出栈并destroy掉,前一个activity被resume并重新显示(还原stop前的UI显示)。

下图表示2个activity切换过程该栈的状态。

53bc98d408cda77ef47df2256276301a.png

用户可以通过返回键令task返回栈中的activity依次弹出,当最后一个activity也被弹出后,该task便不再存在。

如果HOME键被按下,从当前app回到桌面,该app的Task会被移到后台,后台的task所属的所有activity都是stop状态,且back stack依然存在——这个task其实只是失去了和用户交互的焦点。

多个task可以同时存在后台,但是系统也会停止一些activity来释放空间,导致activity的状态丢失。

c6ef3e5db3be4d5151e62b8af280c0c5.png

Back stack中的activity不会被重新排位,如果同一个activity能被其他多个activity启动,这个activity都会创建新实例推入栈中:

cb0fc7e089c763dad5191b6d767b52fb.png

总结Activity和task的默认行为:

Activity A

启动了

Activity B

A

会被

stop

,但状态仍然保存(

UI

,如活动条的位置,

EditText

输入的文字),从

B

返回,

A

resumed

并恢复之前的状态。

点击

HOME

返回桌面,当前的

task

被移到后台,系统会保存

task

中每一个

activity

的状态;直到用户点击

app

图标

返回,该

task

被移回前台,

resume

栈顶的

activity

返回键会导致当前的

activity

从栈顶弹出并被

destroy

,该

activity

状态不会再被保存,前一个

activity

移到栈顶。

Activity

能被实例化多次,包括其它

task

启动它。

管理Task

Android管理task和back stack的默认行为:activity 在同一个任务中创建并置于先进后出的栈中。如果这种默认的行为不能满足我们的app设计,如:为一个activity创建一个新任务(而不是在相同的任务中),或者启动activity时直接打开已存在的实例(而不是直接在栈顶创建新实例),又或者在用户离开这个task的时候清空除了栈顶以外的全部activity。Android提供了一些属性和flag让coder来指定管理的方式。

Intent 也有相关的flag:

android建议一般的app都不要干涉系统按照默认的方式管理activity和task。如果coder必须指定非默认的管理的方式,最好确定这种效果能符合用户的预期。

定义Launch Mode

对 的launchMode可以指定以下值:

Use Cases

Launch Mode

Multiple Instances?

Comments

Normal launches for most activities

"standard"

Yes

默认行为。每次启动一个activity,系统都会在目标task新建一个实例。

Normal launches for most activities

"singleTop"

Conditionally

如果目标activity的实例已经存在于目标task的栈顶,系统会直接使用该实例,并调用该activity的onNewIntent()(不会重新create)

Specialized launches

(not recommended for general use)

"singleTask"

No

在一个新任务的栈顶创建activity的实例。如果实例已经存在,系统会直接使用该实例,并调用该activity的onNewIntent()(不会重新create)

Specialized launches

(not recommended for general use)

"singleInstance"

No

和"singleTask"类似,但在目标activity的task中不会再运行其他的activity,在那个task中永远只有一个activity。

SingleTask的例子:浏览器的browser activity设置了SingleTask只运行在它自己的task中,如果Browser的task现在正在后台当中(task B),而我们的app(task A)的正要打开这个activity,这个task就会被直接移到前台接收我们的intent。

返回键只会将界面返回到当前task的下一个activity,所以Task B回到前台后,返回键会先作用在Task B中,直到最后一个activity被弹出,才会回到我们的Task A栈顶的activity。

89c23f7300ceb8a22c7f575796c8e10d.png

注意:launchMode能被Intent 的flag覆盖。

使用Intent 标志

FLAG_ACTIVITY_NEW_TASK: 等同于 singleTask

FLAG_ACTIVITY_SINGLE_TOP: 等同singleTop

FLAG_ACTIVITY_CLEAR_TOP: 如果该activity已经运行在当前task中,intent指定启动这个activity时,task中在它上面的activity都会被destroy,直到指定的activity位于栈顶,然后它的onNewIntent()被调用。

Affinity

affinity用于指定activity所属的task。默认状态下,一个app中的所有activity都有相同的affinity,所以它们会运行在同一个task。而通过的taskAffinity属性可以指定affinity。

taskAffinity要用中定义的唯一包名来取值,系统通过包名定位到app的默认task。

taskAffinity在以下2种情况中发生作用:

使用FLAG_ACTIVITY_NEW_TASK启动一个activity。如果该activity指定了taskAffinity,系统会将activity实例置于指定的task中。 注意的是,此情况下如果用户点击HOME键,必须要确定有办法能回到那个task中!(例如task所属的app在launcher有自己icon)

activity 设置了 allowTaskReparenting = “true”。 当activity所在的task被移到前台时,该activity会被移动到affinity指定的task中。

清理back stack

如果用户离开一个task很长时间,系统会清理栈顶以下的activity,这样task被从新打开时,栈顶activity就被还原了。coder同样可以通过属性改变这种行为:

alwaysRetatinTaskState: 如果当前栈顶的activity设置此属性为true,task中的所有activity都会被保留状态。

clearTaskOnLaunch:如果当前栈顶的activity设置此属性为true,行为则与alwaysRetatinTaskState相反,每次离开并重新该task,栈顶下的所有activity都会被清除,用户返回task时永远都是activity初始化的状态。

finishOnTaskLaunch: 与clearTaskOnLaunch 相似,不过只作用于单个activity,不影响整个task。即使是栈顶的activity,也会生效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 任务栈空间,【Android】任务和返回栈(tasks and back stack) 的相关文章

  • 一项活动中有多个 YouTube 玩家

    我正在使用 Youtube Android Player API 如下所述 https developers google com youtube android player https developers google com you
  • Mac OS Flutter 构建应用程序包失败:密钥库格式无效

    自从一周以来 我一直在尝试从 flutter 应用程序创建 android 应用程序包 并且我一直遵循创建上传密钥库 https flutter dev docs deployment android给定 flutter 官方网站 在 Ma
  • Sense 手机上的 Android 应用程序主题

    我在有关感应手机上的应用程序的 UI 项目上遇到了障碍 我无法在谷歌或SO上制作搜索查询来找到我所追求的任何参考 有没有办法让我的应用程序主题的 UI 样式与手机当前应用的样式相匹配 我基本上追求不同 UI 小部件 复选框 微调器 按钮等
  • Android 添加新日历

    我已经检查了所有从 Android 应用程序中创建新日历的方法 我见过的唯一方法是在最新的 api 版本中使用新的 Calendar API 但这似乎只有在您使用时才有效CalendarContract ACCOUNT TYPE LOCAL
  • 动态改变ListView中TextView字体颜色

    我正在将 XML 文档绑定到自定义适配器 列表中的所有项目最初的字体颜色均为白色 XML 文档中的一个节点有一个我正在检查的属性 如果设置了该属性 我想将 ListView 中该项目的字体颜色更改为较深的颜色 我的代码似乎最初可以工作 但是
  • 如何更改Android布局中XML片段元素的默认提示值

    默认提示值自动完成 https developers google com places android api autocomplete小部件是Search 如何将该值更改为不同的值String 尝试下面的代码 PlaceAutocomp
  • 通过 adb 将触摸事件发送到设备[重复]

    这个问题在这里已经有答案了 我正在尝试使用以下方式将触摸事件发送到设备adb shell命令 这样我就可以为 UI 测试做一些基本的自动化 我已经关注了之前一些关于此问题的讨论 我确认了获取事件并使用sendevent 为每次触摸发送 6
  • 聚合联系人会自动添加吗?

    您一定也在其他地方看到过这段代码 但显然这个异常没有答案 编辑 如果您来这里寻找通过 vcardio 恢复联系人的解决方案 这就是它 我在使用时得到了这个vCardIO http code google com p vcardio Andr
  • 使用 Android 浏览器的 HTML5 离线存储

    我正在研究如何使用 Android 设备来创建需要离线使用的网站 我还没有找到很多关于Android浏览器如何处理HTML5的localStorage和WebSQL的信息 有人知道这些的尺寸限制吗 它们是否可以更改 我知道移动 Safari
  • 服务中的膨胀视图显示视图,但不显示布局内的 ImageView

    我已经成功地在服务中扩展了我的布局 但是它没有显示ImageView在 的里面Inflated Layout我不知道为什么 我设置了一个onClickListener在图像视图上 它工作得很好 当我单击绿色方块时记录并停止服务 唯一的问题是
  • 为什么找不到ImageView类?

    当我转到图形布局时 我在创建第一个 Android 应用程序 pdf Android Application Development for For Dummies 中的静默切换模式 时遇到了麻烦 在 main xml 文件中插入了 Ima
  • 无法加载(查找)j2v8_android_x86 库

    我有一个使用的 gradle 项目j2v8 android 2 2 1 http mvnrepository com artifact com eclipsesource j2v8 j2v8 android 2 2 1库 为 V8 JS 引
  • 如何在android listview或线性布局中动态设置marginBottom?

    friends 我想使用java代码或动态设置layout marginBottom 在列表视图或线性布局中 有人指导我如何实现这一目标吗 任何帮助 将不胜感激 ListView lst getListView LinearLayout L
  • 带 Retrofit 的简单登录表单

    我开始使用 Retrofit 但我坚持这个简单的步骤 我有一个登录表单 我正在尝试通过服务器进行身份验证 但我无法发送请求 这是我尝试过的 我的改造客户 private static OkHttpClient Builder httpCli
  • 从MySQL php中的特定列获取最大ID和最小ID

    我是新来的php现在尝试从中检索数据MySQL到安卓 这是我的工作细节 table In 检索总小时数函数 我想检索最短 ID 时间 and 最大 ID 超时 from MySQL到安卓通过php最后使用下面的代码来获取总小时数 假设 ID
  • 使用 SearchView 后重置操作栏

    我在用着SearchView小部件以在我的应用程序中启用搜索 首次单击搜索图标后 SearchView小部件会扩展到搜索字段 并且应用程序图标旁边会显示 后退 箭头 如果我单击应用程序图标 操作栏将恢复到初始状态 没有 后退 箭头 并且Se
  • 检测 Android 中 OSM Mapview 是否仍在加载

    我已将 Open Street Maps 包含在我的 Android 应用程序中 在地图视图中 用户应该能够在地图完全加载后捕获屏幕 但目前 即使地图视图仍在加载 用户也可以捕获图像 有人可以告诉我如何检测地图视图何时完全加载吗 下面是我加
  • 错误:Android-XML:将 放置在使用 wrap_content 大小的父元素中可能会导致微妙的错误;使用match_parent

    我是 Android 初学者 正在构建一个linear layout并在布局 XML 文件中收到如下错误 Error Placing a
  • 如何使用 Lint Option StopShip 使 Grade 发布构建失败?

    我读过很多关于StopShipAndroid Lint Check 和 Gradle 支持 http tools android com tips lint checks http tools android com tips lint c
  • Android 列表视图布局 类似于 Google play

    我想实现一个类似于 Google Play 的列表布局 其中每个行都有菜单 请帮助我创建这个 我是否需要创建一个弹出菜单或者有任何选项可以实现此目的 Thanks 看起来您正在尝试完全按照图中所示的方式进行操作 我只是举一个例子来说明我如何

随机推荐