我们知道,一个应用中可能有多个 Activity,而这些 Activity 被以栈的形式管理。当我们新打开 Activity 或者按返回时,会导致 Activity 的入栈/出栈。
有时候我们要进行一些跨应用的操作,比如拍照、P 图、分享到朋友圈,这一系列操作中会有多个应用的 Activity 互相调用,安卓系统是如何管理这些不同应用的 Activity 的呢?
答案你已经猜到了,就是使用 Task。
Task 是指在执行特定任务时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈中。
反应在界面上,当我们点击第三个导航菜单按钮,出现在列表中的就是一个个 Task。
从上图中可看到,一个应用可以包含多个 Task。
(话说回来,微信小程序启动时应该就是新建一个 Task,这样在列表中就可以独立于微信存在。)
应用中的 Task 名默认为包名,我们可以使用 taskAffinity
标签在 AndroidManifest.xml 中指定某个 Activity 要属于的 Task 名称:
<activity
android:name=".activity.launchmode.SingleTaskActivity"
android:label="singleTask"
android:launchMode="singleTask"
android:taskAffinity="top.shixinzhang.task2"/>
设备主屏幕是大多数 Task 的起点。当用户触摸应用启动器中的图标(或主屏幕上的快捷方式)时,该应用的 Task 将出现在前台。
如果应用 Task 不存在(应用最近未曾使用),则会创建一个新 Task,并且该应用的“主”Activity 将作为堆栈中的根 Activity 打开。
正如我们的日常体验,用户通过按“Home” 键离开任务时,当前 Activity 将停止且其 Task 会进入后台。
系统将保留 Task 中每个 Activity 的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则该 Task 将出现在前台并恢复执行堆栈顶部的 Activity。
注意: 后台可以同时运行多个任务。 但是,如果用户同时运行多个后台任务,则系统可能会开始销毁后台 Activity,以回收内存资源,从而导致 Activity 状态丢失。 非 Activity 类型的 Context (比如 ApplicationContext)没有所谓的任务栈。
1.standard:标准模式,默认的
2.singleTop:栈顶复用模式
onCreate
和 onStart
,直接调用 onNewIntent()
方法3.singleTask:栈内复用模式
onNewIntent()
4.singleInstance:栈内唯一
除了 AndroidManifest 文件以外,我们也可以在 startActivity()
时,为 Intent add flag 来改变 Activity 的状态:
Intent intent = new Intent(this, SearchActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
下面是常见的三种与 Task 关联的标志位:
standard
并且也没有使用 FLAG_ACTIVITY_SINGLE_TOP
,会销毁已有的,新建 Activity FLAG_ACTIVITY_SINGLE_TOP
,就会直接调用已有的的 onNewIntent
FLAG_ACTIVITY_NEW_TASK
使用,达到的效果就和 singleTask 差不多了,比如用于通知栏中启动 Activity ,以达到将 Activity 所在 Task 调到前台,同时 clearTop 的效果标志位名称 | 作用 | 备注 |
---|---|---|
FLAG_ACTIVITY_REORDER_TO_FRONT | 将该 Activity 调整到栈顶 | 原来栈中情况是A,B,C,D,在D中启动B(加入该flag),栈中的情况会是A,C,D,B.(调用onNewIntent()) |
安卓开发艺术探索
https://developer.android.com/guide/components/tasks-and-back-stack.html?hl=zh-cn