我误解了FLAG_ACTIVITY_REORDER_TO_FRONT
国旗。我认为活动 YFLAG_ACTIVITY_REORDER_TO_FRONT
活动 C 将保留父项,因此 C 后压将转到 B。不,事实并非如此。FLAG_ACTIVITY_REORDER_TO_FRONT
实际上使 C 转移到新的父 Y(即调用者),但由于父 Y 在 C 之上,所以 C 后压将无法转到 Y 并最小化/隐藏到背景。
我也误解了我的代码创建了 2 个堆栈,但实际上它只是一个堆栈。我必须用FLAG_ACTIVITY_MULTIPLE_TASK
它来做多层。
我还需要launchMode
在清单中定义正确:
- 启动器活动 A 和 X 都必须
singleInstance
在清单中定义。
- 主页活动 B 和 Y 都必须
singleTop
在清单中定义。
- 其他活动 C 和 Z ...等必须
singleTask
在清单中定义。
Activity A 必须Intent.FLAG_ACTIVITY_MULTIPLE_TASK
在启动主页 B 时设置标志。X 也应Intent.FLAG_ACTIVITY_MULTIPLE_TASK
在启动主页 Y 时设置标志。
如果选项卡任务之前已经开始,则循环以重新排序所有相同任务活动(存储在全局堆栈列表中)的有效标志是(moveTaskToBack(true);
单行也可以,但它不能回到前台):
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
|Intent.FLAG_ACTIVITY_NEW_TASK
|Intent.FLAG_ACTIVITY_NO_ANIMATION);
p/s:以上在 Android 5 和 6 中不起作用,只会将单个顶部活动重新排序到前面,所以我需要添加android.permission.REORDER_TASKS
清单并执行此操作(更多信息,请参阅此错误报告):
ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (final Activity a : YStackClasses) {
if (IsBeforeAndroidNougat && (tasksManager != null)) {
tasksManager.moveTaskToFront(a.getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION);
} else {
//Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
}
}
如果选项卡任务从未启动,则应在不设置任何特殊标志的情况下启动启动器活动。
为了防止点击启动器由于 刷新singleInstance
,我还必须检查 A 和 B,将其放在之前setContentView
和finish()
/之前return;
。
if (getIntent() != null && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
//figure out latest activity and it's home activity, and reorder to front, and its entire task stack will focus on top.
}
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
将不再自动清除所有活动以刷新应用程序,解决方案是ActivityCompat.finishAffinity(desiredTask's Top Act);
,这将删除顶部活动下方的所有活动,而不影响其他任务堆栈。
如果该类是重用的,例如 C1、C2,那么我必须使用startActivityForResult(intent, dummyResponse);
它来强制它在同一类之上创建新的活动。但是当 A 启动活动 B 时不要这样做,因为startActivityForResult
需要单个任务并忽略启动singleInstance
模式,请参阅此线程。并且不要做ForResult
内部onNewIntent()
可能导致页面在堆栈中生成两次(第二个页面不会立即生成,而是仅在返回时生成)。但是我可以做到ForResult
在调用者中onNewIntent()
生效。
我还需要这样做以使 backpress 在家庭活动中按预期工作以隐藏应用程序并能够返回正确的任务页面。我不使用TASK_ON_HOME
(当启动主页 B 类时)标志,因为它只是单个任务方向(即前景到固定活动而不是取决于先前的顶级任务活动):
@Override //B class
public void onBackPressed() {
moveTaskToBack(true); //B task stack
if (YStackClasses.size() > 0) { //Y task stack
try {
YStackClasses.get(0).moveTaskToBack(true);
} catch (Exception e) {
e.printStackTrace();
}
}
super.onBackPressed();
}
请注意,即使由于崩溃而自动重新启动,应用程序堆栈也可能会缓存,因此有时您需要重新启动两次才能使其恢复到初始堆栈状态进行测试,否则您会得到错误的结论。
就是这样,这个答案可能缺少代码细节,但如果你遇到像我一样的“回压时隐藏到后台”问题,它应该会有所帮助,你可以了解如果你在一步中设置了错误的标志或launchMode
在清单中的一项活动中定义错误。