我目前设法允许用户在两个不同的活动组(让我们说4个活动类别A / B组和X / Y组)之间切换,并通过FLAG_ACTIVITY_REORDER_TO_FRONT
标志进行切换,但是我注意到有一些奇怪的行为:
A ->(start activity) X
X ->(reorder to front) A
X , A ->(start) B ->(start) B2
A , B , B2 ->(reorder to front) X ->(start) Y
X , Y ->(reorder to front) A , B , B2
X , Y , A , B <-(press back, app hide to background, B2 destroyed) B2
X , Y , A , B (click to foreground, B is here just fine)
从B2
返回后,如何防止应用隐藏到后台?
我注意到它仅在同一类中发生(B
和B2
是同一类),如果我使用B
和C
,就不会出现此类问题,我想知道背后的原因是什么。
X ->(start) Y
也是复制它的关键。
我尝试使用应用程序级别的自定义实例列表来检测B2
的{{1}}的{{1}}和onPause()
和isFinishing()
,但是它将始终即使使用startActivty()
也会调用B
的{{1}},这使我认为这不是正确的解决方案。正确的解决方案应该弄清楚如何防止应用隐藏到后台。
答案 0 :(得分:0)
我误解了FLAG_ACTIVITY_REORDER_TO_FRONT
标志。我认为活动Y FLAG_ACTIVITY_REORDER_TO_FRONT
的活动C将保留父项,因此C后退将转到B。不,不是这样。 FLAG_ACTIVITY_REORDER_TO_FRONT
实际上是将C转移到新的父Y(即调用方),但是由于父Y位于C的顶部,因此C backpress将无法转到Y并最小化/隐藏到背景。
我也误解了我的代码创建2个堆栈,但实际上它只是单个堆栈。我必须使用FLAG_ACTIVITY_MULTIPLE_TASK
使其多堆。
我还需要在清单中定义正确的launchMode
:
singleInstance
表现。 singleTop
在清单中。 singleTask
。活动A在开始首页B时必须设置标志Intent.FLAG_ACTIVITY_MULTIPLE_TASK
。
在开始首页Y时,X还应设置标志Intent.FLAG_ACTIVITY_MULTIPLE_TASK
。
如果选项卡任务之前已经开始,则循环以对所有相同的任务活动(存储在全局堆栈列表中)重新排序的有效标志是(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
并执行此操作(更多信息,{{3 }}):
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;
之前。 / p>
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
launchMode see this bug report,则不要这样做。并且不要在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();
}
请注意,即使由于崩溃而自动重新启动,应用程序堆栈也可能会缓存,因此有时您需要重新启动两次以使其回到初始堆栈状态进行测试,否则您将得出错误的结论。
就是这样,此答案可能缺少代码详细信息,但是如果您遇到像我这样的“ backpress时隐藏背景” 问题,它应该会有所帮助,您可以了解很难达到预期的效果如果您在一个步骤中设置了错误的标志,或者在清单中的活动之一中定义了错误的launchMode
,则会发生这种情况。