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

我使用LG的Developer程序借用LG G4,然后重现了问题。基本上,该应用程序停止运行不会引发任何异常。通常,它最终会给出“应用程序无响应”错误。我还观察到了操作系统偶尔完全崩溃的情况,很少能成功启动游戏。

我找到了一种解决方法,似乎可以解决问题,因此,在下面回答我自己的问题,以防其他人遇到此问题。 (尽管真正的解决方案是让LG不要在Android OS中引入错误。)

最佳答案

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

如果在渲染线程尝试获取锁之前立即插入thread.sleep(),问题将消失。我完全是偶然发现的:我在其中插入了一条log语句,该log语句本身造成了足够的延迟,导致游戏开始工作!这是我的(简化的)代码结构和修复程序:

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 OS中一个令人讨厌的潜在错误。客户报告说,其他LG手机没有此错误。我正在将问题提交给LG分别。)

关于java - LG G4在基于Lunar Lander的Android游戏启动时崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34936057/

10-12 05:37