【问题标题】:LG G4 crashes on start of Lunar Lander-based Android gameLG G4 在基于月球着陆器的 Android 游戏开始时崩溃
【发布时间】:2016-01-21 23:03:51
【问题描述】:

我基于 Google 的 Lunar Lander 示例编写了一个 Android 游戏(使用 Android Canvas 进行 2D 绘图)。自 2009 年以来,该游戏在所有 Android 设备上运行良好,但用户最近报告说它无法在 LG G4 上启动。有时 G4 会完全死机,因此用户必须卸下电池才能重新启动它。

我用 LG 的 Developer program 借了一台 LG G4,重现了这个问题。基本上应用程序会停止而不会引发任何异常。通常它最终会给出“应用程序无响应”错误。我还观察到操作系统偶尔会完全崩溃,并且很少会成功启动游戏。

我找到了一个似乎可以解决问题的解决方法,所以我在下面回答我自己的问题,以防其他人遇到这个问题。 (虽然真正的解决方案是让 LG 不将错误引入 Android 操作系统。)

【问题讨论】:

    标签: java android crash jvm-crash lg


    【解决方案1】:

    我通过添加日志语句来执行“二进制搜索”以查找程序冻结的行。我发现冻结发生在初始启动时,当渲染线程试图获取画布上的锁时。

    如果我在渲染线程尝试获取锁之前立即插入 thread.sleep(),问题就会消失。我完全是偶然发现的:我在那里插入了一条日志语句,而日志语句本身造成了足够的延迟,以至于游戏开始运行!这是我的(简化的)代码结构和修复:

    public class theview extends SurfaceView implements SurfaceHolder.Callback {
        private final SurfaceHolder mSurfaceHolder;
        public theview(Context context, AttributeSet attrs) {
            super(context, attrs);
            mSurfaceHolder = getHolder();
            //(other game-initialization code omitted)
            thread = new LunarThread();
    
        public void surfaceCreated(SurfaceHolder holder) {
            //(other game-resuming code omitted)
            mRun=True;
            thread.start();
        }
    
        class LunarThread extends Thread {
            @Override
            public void run() {
                Canvas c=null;
                while (mRun) {
                    try {
                        LunarThread.sleep(0, 1); // <---the LG G4 needs this line or the game doesn't load! Sleep duration didn't matter.
                    }catch(InterruptedException ignored){}
    
                    if(c==null){
                        LunarThread.yield();//app is still loading; wait for it.
                    }
                    try {
                        c = mSurfaceHolder.lockCanvas(null); // <---- this is the line where the LG G4 freezes without the above sleep()
                        if (c != null) {
                            synchronized (mSurfaceHolder) {
                                if (mMode == STATE_RUNNING) doPhysics();
                                doDraw(c);
                            }
                        }
                    }
                    finally {
                        // do this in a finally so that if an exception is thrown
                        // during the above, we don't leave the Surface in an
                        // inconsistent state
                        if (c != null) {
                            mSurfaceHolder.unlockCanvasAndPost(c);
                        }
                    }
    
    }
    

    1ns 延迟足够短,我刚刚为所有手机添加了它。

    (不言而喻,但显然这只是对 LG G4 定制版 Android 操作系统中一个令人讨厌的潜在错误的缓解。客户报告说其他 LG 手机不会发生这种情况。我正在提交单独发给 LG。)

    【讨论】:

    • 如果程序崩溃了,99% 的时间在 logcat 中有一个堆栈跟踪,告诉你哪一行崩溃了。没有理由对日志进行二进制搜索。如果你添加睡眠来修复某些东西,你并没有真正修复它。花一些时间找出真正的解决方案,而不是在这里发布糟糕的 hack。
    • @GabeSechan 正如我在问题中所说,它没有引发任何异常。只是操作系统级别的崩溃。我正在记录一个避免操作系统级崩溃的解决方法。当我正确调用该函数时,您如何建议我进一步调试在 LG 的 Android 系统函数的闭源版本中发生的崩溃?
    猜你喜欢
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 2018-11-01
    • 2019-10-07
    • 2016-05-21
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    相关资源
    最近更新 更多