使用FLAG_ACTIVITY_REORDER_TO_FRONT在永久运行的UI活动之间切换导致“无窗焦点”错误 [英] Using FLAG_ACTIVITY_REORDER_TO_FRONT to switch among persistently running UI activities leads to "no window focus" error

查看:600
本文介绍了使用FLAG_ACTIVITY_REORDER_TO_FRONT在永久运行的UI活动之间切换导致“无窗焦点”错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是保持两个用户界面活动的生命,并在他们之间来回切换,而不必杀死/重新启动其中任何一个。但是,使用 FLAG_ACTIVITY_REORDER_TO_FRONT 来执行此操作会产生严重的副作用:恢复之前的活动(当前正在后台运行)时丢失窗口焦点。

我用5分钟的时间用两个Hello World活动创建了一个简单的应用程序,证明了这个问题。
$ b


  1. 应用程序从Activity A开始,它只是显示一个按钮(没有别的),叫做Launch B。
  2. 按下这个按钮 - 执行 startActivity(FLAG_ACTIVITY_REORDER_TO_FRONT,ActivityB .class)。

  3. 活动B变为活动状态,显示一个名为Launch A的按钮。按下此按钮 - 执行 startActivity(FLAG_ACTIVITY_REORDER_TO_FRONT,ActivityA.class)。

  4. 活动A的 onResume )按预期的方式调用,一切都很正常(我可以再次看到Activity A的内容)。
  5. 按下设备的Back键,错误将发生在100%的时间:


    lockquote

    E / ActivityManager(513):原因:输入调度超时(等待
    ,因为没有窗口有焦点,但有一个专注的应用程序
    最终可能会在完成启动时添加一个窗口。)

    I / WindowState(513):WIN DEATH:窗口{5294687c u0
    com.android.launcher / com.android.launcher2.Launcher}



    ViewRootImpl(8066):由于没有窗口焦点而丢失事件
    KeyEvent {action = ACTION_DOWN,keyCode = KEYCODE_BACK,scanCode = 0,
    metaState = 0,flags = 0xc8, repeatCount = 1,eventTime = 14965546,
    downTime = 14965045,deviceId = -1,source = 0x101}

    从用户的角度来看,窗口死亡的实际结果本质上是一个崩溃 - Android将用户从应用程序抛出回主屏幕,尽管技术上应用程序仍然在后台运行。



    我调试了这个,发现Activity A是可见的,但没有焦点的原因是因为Activity A的 onWindowFocusChanged()不叫就像通常那样(即使调用onResume())。 这与事实有关,即活动B在后台仍处于活动状态(尽管B明显失去了重点 - 为B调用了onWindowFocusChanged(false),以及onStop()) 。 我知道这是因为在步骤4之后,如果我立即在Activity B上调用finish(),则将调用Activity A的onWindowFocusChanged(true),并且一切正常。事件B仍然是活动的,但不是集中在某种程度上会干扰活动A重新获得应有的焦点。这是一个Android的错误,或者我错过了什么?



    请注意,如果活动A有多个视图,并在上面的步骤6后触摸其中一个视图,我会得到相同的由于没有窗口焦点的下降事件的错误,虽然不是100%的时间出于某种原因。 中提供的解决方法 详细信息?id = 63570#c15rel =nofollow> https://code.google.com/p/android/issues/detail?id=63570#c15 对我来说很好,可以解决问题活动没有得到窗口焦点:$ b​​
    $ b pre $ 保护无效的onNewIntent(意图意图){
    super.onNewIntent(intent); ((intent.getFlags()| Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)> 0){
    if(android.os.Build.VERSION.SDK_INT> = 19&&!isTaskRoot()) {
    ActivityManager tasksManager =(ActivityManager)getSystemService(ACTIVITY_SERVICE);
    tasksManager.moveTaskToFront(getTaskId(),ActivityManager.MOVE_TASK_NO_USER_ACTION);





    这也需要权限 AndroidManifest.xml

     < uses-permission android:name = android.permission.REORDER_TASKS/> 

    我在 Espresso 测试得到这样的错误:
    $ b

    java.lang.RuntimeException:等待视图层次结构的根具有窗口焦点,而不是请求布局超过10秒。如果你指定了一个非默认的根匹配器,它可能会选择一个永远不会关注的根。否则,一些事情是严重错误的。


    My objective is to keep two UI activities alive and to switch back and forth between them at will without having to kill/restart either of them. But there is a serious side effect of using FLAG_ACTIVITY_REORDER_TO_FRONT to do this: a loss of window focus when I resume a previous activity (that is currently running in the background).

    I proved this issue by spending 5 minutes creating a simple application with two "Hello World" activities.

    1. The app starts with Activity A, which simply shows a button (nothing else) called "Launch B".
    2. Press this button -- this executes startActivity(FLAG_ACTIVITY_REORDER_TO_FRONT, ActivityB.class).
    3. Activity B becomes active, which shows simply shows a button called "Launch A".
    4. Press this button -- this executes startActivity(FLAG_ACTIVITY_REORDER_TO_FRONT, ActivityA.class).
    5. Activity A's onResume() is called as expected and everything looks fine (I can see Activity A content again).
    6. Press the device's Back key and this set of errors will occur 100% of the time:

    E/ActivityManager( 513): Reason: Input dispatching timed out (Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.)

    I/WindowState( 513): WIN DEATH: Window{5294687c u0 com.android.launcher/com.android.launcher2.Launcher}

    W/ViewRootImpl( 8066): Dropping event due to no window focus: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0xc8, repeatCount=1, eventTime=14965546, downTime=14965045, deviceId=-1, source=0x101 }

    (The practical result of the window death is essentially a "crash" from the user's point of view -- Android throws the user out of the app back to the Home screen, though technically the application remains running in the background.)

    I debugged this and found that the reason Activity A is visible but doesn't have focus is because activity A's onWindowFocusChanged() is NOT called like it normally does (even though onResume() is called). This has something to do with the fact with Activity B is still active in the background (even though clearly B has lost focus -- onWindowFocusChanged(false) was called for B, as well as onStop()). I know this because after step 4 above if I immediately call finish() on Activity B, Activity A's onWindowFocusChanged(true) WILL be called and everything is normal. The fact that Activity B is still active but not focused somehow interferes with Activity A regaining focus like it should. Is this an Android bug or am I missing something?

    Note that if Activity A had multiple views in it and I were to touch one of those views after step 6 above, I would get the same "Dropping event due to no window focus" error, though not 100% of the time for some reason.

    解决方案

    The workaround provided in https://code.google.com/p/android/issues/detail?id=63570#c15 worked pretty well for me to resolve the issue of Activity not getting window focus:

    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if ((intent.getFlags() | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) > 0) {
            if (android.os.Build.VERSION.SDK_INT >= 19 && !isTaskRoot()) {
                ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
                tasksManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION);
            }
        }
    }
    

    This will also need the permission in AndroidManifest.xml

    <uses-permission android:name="android.permission.REORDER_TASKS" />
    

    I actually run into this issue in Espresso test getting such error:

    java.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not be requesting layout for over 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Otherwise, something is seriously wrong.

    这篇关于使用FLAG_ACTIVITY_REORDER_TO_FRONT在永久运行的UI活动之间切换导致“无窗焦点”错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆