【问题标题】:Android UI Thread blocked in new ActivityAndroid UI 线程在新活动中被阻止
【发布时间】:2014-06-03 06:02:11
【问题描述】:

我正在开发一个在工作线程上处理画布绘图的小型 Android 游戏。游戏结束后,该线程应该开始下一个活动,但不知何故,UI 线程似乎因启动新功能而被阻塞。

这是我的游戏主循环:

while(true)
    // Perform Ticks until the player makes a mistake
    c = _surfaceHolder.lockCanvas();
    if ((toDraw = rh.performTick()) == null) {
         lose();
         break;
     }
     _surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
}

函数performTick()处理游戏逻辑并在游戏结束时返回nulldraw()进行渲染。两个函数都能完美运行 - 问题是 lose(),它只会启动一个新的 Activity:

    protected void lose() {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(_context, MainMenu.class);
                _context.startActivity(intent);
            }
        });
    }

当游戏结束时,新的 Activiy (MainMenu) 正常启动,但不会对任何触摸事件做出反应。没有 LogCat 输出,也没有发生异常。更糟糕的是,lose() 在主循环开始之前被调用时正常工作。

我已经为此工作了好几天了。我尝试直接从工作线程启动活动(不使用lose() 中的Handler)并在互联网上搜索了几个小时 - 没有任何帮助。似乎 UI 线程以某种方式被阻塞或陷入无限循环,我不知道如何解决这个问题。

一切都在 Nexus 4 设备上调试。

顺便说一句:MainMenu.onCreate() 在以其他方式启动时正常工作。

请帮忙, MA3o

【问题讨论】:

    标签: android multithreading ui-thread blocked


    【解决方案1】:

    当 if 语句为真时,您不会解锁画布。 Break 会让你摆脱这段时间,让画布处于锁定状态。

    while(true)
        // Perform Ticks until the player makes a mistake
        c = _surfaceHolder.lockCanvas();
        if ((toDraw = rh.performTick()) == null) {
             lose();
             break;
         }
    
         // this line won't be executed whether the if statement above is true
         _surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));
    }
    

    你也应该在 if 语句中解锁(在 loss() 之前或之后)。

    【讨论】:

    • 很简单...工作正常,非常感谢!
    【解决方案2】:

    相反,如果While(true) 你可以有While(myVar) 其中myVar 是一个布尔值,当游戏应该运行时为真,当你调用lose() 时设置为假在你的情况下,你继续画虽然你没有需要。

    【讨论】:

    • 它不会继续绘制,因为if语句中的break取消了while。
    • 是的,我在评论 Ma3o 写的不是你的,你的完全正确,我的解决方案将运行 '_surfaceHolder.unlockCanvasAndPost(draw(toDraw,c));'在用户已经迷路之后再一次,这可能不是他想要的。
    • 即使这也可以解决问题(因为 while 循环将完成并再次解锁画布),但答案本身是错误的。关键字break;用于立即结束一个循环,与它的正常行为无关,所以当lose()被调用并且程序停止绘图时循环结束
    猜你喜欢
    • 2012-08-27
    • 2011-09-07
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    相关资源
    最近更新 更多