当前位置: 首页 > 知识库问答 >
问题:

如何修复应用程序在重新排序前后转到后台

唐修诚
2023-03-14

我目前设法允许用户在两个不同的活动组(比如说4个活动类A/B组和X/Y组)之间切换,并通过FLAG\u activity\u REORDER\u切换到\u FRONTFLAG,但我注意到有一些奇怪的行为:

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返回时隐藏到后台?

我注意到它只发生在同一个类中(BB2是同一个类),如果我使用BC,就不会出现这样的问题,我想知道背后的原因是什么。

X-

我尝试使用应用程序级自定义实例列表来检测B2onPause()isFinishing()startActivty()B,但它始终会调用BonCreate(),即使使用标记活动\u重新排序\u到前面,这让我觉得这不是正确的解决办法。正确的解决方案应该找出如何防止应用程序隐藏到后台。


共有1个答案

柯星辰
2023-03-14
匿名用户

我误解了FLAG\u ACTIVITY\u REORDER\u TO\u FRONT标志。我认为活动Y标记\u活动\u重新排序\u到\u前端活动C将保留父级,因此C将返回到B。不,情况并非如此<代码>标记\u活动\u重新排序\u到\u前台实际上将C传输到新的父级Y(即调用者),但由于父级Y位于C之上,因此C backpress将无法转到Y并最小化/隐藏到后台。

我也误解了我的代码创建2堆栈,但实际上它只是单个堆栈。我必须使用FLAG_ACTIVITY_MULTIPLE_TASK使其成为多个堆栈。

我还需要在清单中定义正确的启动模式

  • 启动程序活动A和X必须在清单中定义为singleInstance
  • 主页活动B和Y必须在清单中定义为singleTop
  • 其他活动C和Z…等必须在清单中定义为singleTask

活动A必须在启动主页B时设置标志Intent。在启动主页Y时,标记活动多任务。X还应设置标志Intent。标记活动多任务

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\u任务,并执行此操作(更多信息,请参阅此错误报告):

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完成()/返回;早。

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.finishafinity(desiredTask的顶级行为) ,它将删除顶部activitiy下面的所有Activities,而不会影响其他任务堆栈。

如果类是重用的,比如C1、C2,那么我必须使用startActivityForResult(intent、dummyResponse)强制它在同一个类上创建新的活动。但不要在启动活动B时执行此操作,因为startActivityForResult需要单个任务,并且忽略singleInstance启动模式,请参阅此html" target="_blank">线程。并且不要在onNewIntent()内部执行ForResult,这可能会导致在堆栈中生成两次页面(第二个页面不会立即生成,而只在返回时生成)。但是我可以在调用onNewIntent()时执行ForResult,以使其生效。

我还需要这样做,使反压工作作为预期的家庭活动隐藏应用程序,并能够回到正确的任务页面。我不使用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,您可以了解实现预期行为的难度。

 类似资料:
  • 当用户按下注册按钮并将值传递给HomeActivity.java时,我试图从数据库(在LoginActivity.java上创建)传递变量。在我使用意图附加和捆绑之前,代码工作正常(除了传递变量)。但是当我把新代码,应用程序崩溃后,立即我按下注册按钮 我试图寻找另一个可能的重复问题,但没有一个问题与我的问题相同。他们中的大多数人忘了把活动放在android清单上,但我把LoginActivity放

  • 问题内容: 对于典型的最典型的面向Internet的网站,当您通过关闭选项卡( 无需注销 )登录并离开该网站(然后 注销 ),然后再次访问时,可能不需要您重新指定凭据或登录,您可以直接登录。 这一切在后端如何发生?如何在我的JSF 2.1应用程序中启用这种机制? 在Tomcat7服务器上使用JSF 2.1 问题答案: 这基本上是通过一个长寿的cookie完成的。JSF API不提供此功能,因为它只

  • 本文向大家介绍Android应用程序转到后台并回到前台判断方法,包括了Android应用程序转到后台并回到前台判断方法的使用技巧和注意事项,需要的朋友参考一下 我们知道,当我们按返回或Home键退出应用程序的界面时,应用程序会在后台被挂起。这么设计的好处是,由于应用被系统缓存在内存中,那么在用户打开启动应用时就可以通过调用缓存,快速启动应用。当然,由于当今内存和处理器能力的限制,系统会自动关闭一些

  • 我使用尝试在活动之间切换。因为这是一辆马车(回来时有时会藏起来),所以我试着潜入其中。 并没有真正使活动移动到顶部,正如我从adb中看到的,活动顺序从未改变: 仅从以下位置更改“焦点状态”: 为此: 但如果我按home按钮四处玩,我可以看到launcher窗口能够“真正移动”到顶部: 由于隐藏/取消隐藏到后台以移动窗口是可能的,这让我想知道是否有可能通过编程方式将mySecondActivity置

  • 我有一个类似于以下内容的HashMap: 有什么建议吗? 我首先比较值,只有在值重复的情况下才比较键。所以我同时使用键和值,而不仅仅是值。

  • null 而当app在后台时,系统托盘总是显示一个到达一个重复的通知(如收到通知a,系统托盘显示2个通知a)。 怎么解决这个问题? 编辑:添加的代码 我扩展了 类,并在 方法中包含该类 这是项目中我使用NotificationManager的唯一部分。 另外,我尝试在这个方法上添加一个日志。当应用程序处于前台时调用onMessageReceived。当应用程序在后台时,它不会被调用