Android的应用程序崩溃的onPause() - 逻辑工作在一个项目中的另一个失败 [英] Android App Crashes onPause() -- Logic Works in One Project Fails in Another

查看:449
本文介绍了Android的应用程序崩溃的onPause() - 逻辑工作在一个项目中的另一个失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前,我开始比赛,我目前正在研究,我建立了下面的逻辑来处理暂停。一切都完美的作品在那里,我这样想着。在测试应用程序,逻辑仍然有效,这意味着我把它弄坏了别的地方沿线。基于以下逻辑和LogCat中的邮件,你可以点我,我应该寻找的方向?我不知道如何跨$ P $磅以下错误。任何帮助将是非常欢迎。我不能确切要求,如果它曾经进入睡眠状态,重新启动游戏。

谢谢!

MainGamePanel.java

 公共无效暂停(){
    mSensorManager.unregisterListener(本);}公共无效简历(上下文的背景下){
    mSensorManager.registerListener(这一点,mAccelerometer,SensorManager.SENSOR_DELAY_FASTEST);
}公共无效的destroy(){
    thread.setRunning(假);    如果(线程!= NULL)
    {
        螺纹killThread =螺纹;
        螺纹=无效;
        killThread.interrupt();
    }}@覆盖
公共无效surfaceCreated(SurfaceHolder持有人){
    //继续线程
    同步(线程){
        thread.pleaseWait = FALSE;
        thread.notifyAll();
    }}@覆盖
公共无效surfaceDestroyed(SurfaceHolder持有人){
    //暂停线程
    同步(线程){
        thread.pleaseWait =真;
    }}

主要活动:

  //重新启动后的onPause加速度计
保护无效onResume(){
    super.onResume();
    viewPanel.resume(本);}//标准方法,当应用程序失去焦点运行。
//这个运行在viewPanel中,这样的暂停()函数
//加速度计可以暂停。
保护无效的onPause(){
    super.onPause();
    viewPanel.pause();}保护无效的onDestroy(){
    super.onDestroy();
    viewPanel.destroy();
}@覆盖
公共布尔的onkeydown(INT键code,KeyEvent的事件){
    如果(键code == KeyEvent.KEY code_BACK&放大器;&安培; event.getRepeatCount()== 0){
        //做回事情。
        viewPanel.backHit();
        返回true;
    }    返回super.onKeyDown(键code,事件);
}

和我MainThread.java文件:

 包com.petronicarts.stormthecastle;进口com.petronicarts.stormthecastle.MainGamePanel;进口android.graphics.Canvas;
进口android.graphics.Matrix;
进口android.view.SurfaceHolder;公共类MainThread继承Thread {私人SurfaceHolder surfaceHolder;
私人MainGamePanel的GamePanel;
私人布尔运行;
公共布尔PLEASEWAIT = TRUE;
公共无效setRunning(布尔运行){
    this.running =运行;
}公共MainThread(SurfaceHolder surfaceHolder,MainGamePanel的GamePanel){
    超();
    this.surfaceHolder = surfaceHolder;
    this.gamePanel =的GamePanel;
}@覆盖
公共无效的run()
{
    帆布油画;    字模=新的Matrix();
    。矩阵preSCALE(gamePanel.getScaleX(),gamePanel.getScaleY());
    长的startTime,elapsedTime;
    STARTTIME = System.currentTimeMillis的();
    elapsedTime = System.currentTimeMillis的() - startTime时;    而(运行){
        如果(!PLEASEWAIT){
            帆布= NULL;            //尝试锁定独家像素编辑画布表面上
            尝试{
                画布= this.surfaceHolder.lockCanvas();
                canvas.setMatrix(矩阵);
                同步(surfaceHolder){
                    //更新游戏状态
                    STARTTIME = System.currentTimeMillis的();
                    this.gamePanel.update(elapsedTime);                    //绘制面板上的画布
                    this.gamePanel.onDraw(画布);                    elapsedTime = System.currentTimeMillis的() - startTime时;                }
            } {最后
                //在异常的情况下,表面不留下
                //不一致状态
                如果(帆布!= NULL){
                    surfaceHolder.unlockCanvasAndPost(画布);
                }
            } //最后结束
        }
        其他{
            同步(本){
                尝试{
                    等待();
                }赶上(例外五){}
            }
        }
    }
}
}

在LogCat中错误:

  15 06-07:56:45.852:E / AndroidRuntime(3374):致命异常:主要
06-07 15:56:45.852:E / AndroidRuntime(3374):显示java.lang.NullPointerException
06-07 15:56:45.852:E / AndroidRuntime(3374):在com.petronicarts.stormthecastle.MainGamePanel.surfaceDestroyed(MainGamePanel.java:312)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:600)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.SurfaceView.updateWindow(SurfaceView.java:486)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:213)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.View.dispatchDetachedFromWindow(View.java:6232)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1868)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.ViewRoot.doDie(ViewRoot.java:2958)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.ViewRoot.die(ViewRoot.java:2928)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:254)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.view.Window $ LocalWindowManager.removeViewImmediate(Window.java:445)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3201)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:330​​6)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.app.ActivityThread.access $ 1600(ActivityThread.java:132)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1055)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.os.Handler.dispatchMessage(Handler.java:99)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.os.Looper.loop(Looper.java:150)
06-07 15:56:45.852:E / AndroidRuntime(3374):在android.app.ActivityThread.main(ActivityThread.java:4312)
06-07 15:56:45.852:E / AndroidRuntime(3374):在java.lang.reflect.Method.invokeNative(本机方法)
06-07 15:56:45.852:E / AndroidRuntime(3374):在java.lang.reflect.Method.invoke(Method.java:507)
06-07 15:56:45.852:E / AndroidRuntime(3374):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:849)
06-07 15:56:45.852:E / AndroidRuntime(3374):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
06-07 15:56:45.852:E / AndroidRuntime(3374):在dalvik.system.NativeStart.main(本机方法)


解决方案

您可能不应该对线程变量同步(这样做,在 surfaceDestroyed )。它设置为其他地方(在摧毁)。

实际上,在一般情况下,它总是一个坏主意在非最终对象引用同步

I before I started the game I'm currently working on, I built the following logic to handle pausing. Everything works perfectly in there, or so I thought. In the test app that logic still works, which means I broke it somewhere else along the line. Based on the logic below and the LogCat messages, can you point me in the direction that I should be looking? I don't know how to interpret the errors below. Any help would be very welcome. I can't exactly require the game to be restarted if it ever goes to sleep.

Thanks!

MainGamePanel.java

public void pause() {
    mSensorManager.unregisterListener(this);

}

public void resume(Context context) {
    mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_FASTEST);  
}

public void destroy() {
    thread.setRunning(false);

    if (thread != null)
    {
        Thread killThread = thread;
        thread = null;
        killThread.interrupt();
    }   

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    //continue the thread
    synchronized (thread) {
        thread.pleaseWait = false;
        thread.notifyAll();
    }

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    //pause the thread
    synchronized (thread) {
        thread.pleaseWait = true;
    }

}

Main Activity:

//Restarts the accelerometer after onPause
protected void onResume() {
    super.onResume();
    viewPanel.resume(this);

}

//Standard Method run when the Application loses focus.
//This runs the pause() function in the viewPanel so that
//the accelerometer can be paused.
protected void onPause() {
    super.onPause();   
    viewPanel.pause();

}

protected void onDestroy() {
    super.onDestroy();
    viewPanel.destroy();
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
        // do something on back.
        viewPanel.backHit();
        return true;
    }

    return super.onKeyDown(keyCode, event);
}

And my MainThread.java file:

    package com.petronicarts.stormthecastle;

import com.petronicarts.stormthecastle.MainGamePanel;

import android.graphics.Canvas;
import android.graphics.Matrix;
import android.view.SurfaceHolder;

public class MainThread extends Thread {

private SurfaceHolder surfaceHolder;
private MainGamePanel gamePanel;
private boolean running;
public boolean pleaseWait = true;
public void setRunning(boolean running) {
    this.running = running;
}

public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
    super();
    this.surfaceHolder = surfaceHolder;
    this.gamePanel = gamePanel;
}

@Override
public void run() 
{
    Canvas canvas;

    Matrix matrix = new Matrix();
    matrix.preScale(gamePanel.getScaleX(), gamePanel.getScaleY());
    long startTime, elapsedTime;
    startTime = System.currentTimeMillis();
    elapsedTime = System.currentTimeMillis() - startTime;

    while (running) {
        if(!pleaseWait) {
            canvas = null;

            // try locking the canvas for exclusive pixel editing on the surface
            try {
                canvas = this.surfaceHolder.lockCanvas();
                canvas.setMatrix(matrix);
                synchronized (surfaceHolder) {
                    // update game state
                    startTime = System.currentTimeMillis();
                    this.gamePanel.update(elapsedTime);

                    // draws the canvas on the panel
                    this.gamePanel.onDraw(canvas);

                    elapsedTime = System.currentTimeMillis() - startTime;

                }
            } finally {
                // in case of an exception the surface is not left in
                // an inconsistent state
                if (canvas != null) {
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }   // end finally            
        }
        else {
            synchronized (this) {
                try {
                    wait();
                } catch (Exception e) { }
            }
        }
    }
}
}

The LogCat Errors:

06-07 15:56:45.852: E/AndroidRuntime(3374):     FATAL EXCEPTION: main
06-07 15:56:45.852: E/AndroidRuntime(3374):     java.lang.NullPointerException
06-07 15:56:45.852: E/AndroidRuntime(3374):     at com.petronicarts.stormthecastle.MainGamePanel.surfaceDestroyed(MainGamePanel.java:312)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:600)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.SurfaceView.updateWindow(SurfaceView.java:486)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:213)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.View.dispatchDetachedFromWindow(View.java:6232)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1868)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewRoot.doDie(ViewRoot.java:2958)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.ViewRoot.die(ViewRoot.java:2928)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:254)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.view.Window$LocalWindowManager.removeViewImmediate(Window.java:445)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3201)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3306)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread.access$1600(ActivityThread.java:132)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1055)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.os.Looper.loop(Looper.java:150)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at android.app.ActivityThread.main(ActivityThread.java:4312)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at java.lang.reflect.Method.invokeNative(Native Method)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at java.lang.reflect.Method.invoke(Method.java:507)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
06-07 15:56:45.852: E/AndroidRuntime(3374):     at dalvik.system.NativeStart.main(Native Method)

解决方案

You should probably not synchronize on the thread variable (doing that in surfaceDestroyed). It's set to null elsewhere (in destroy).

Actually, in general, it's always a bad idea to synchronize on a non final object reference.

这篇关于Android的应用程序崩溃的onPause() - 逻辑工作在一个项目中的另一个失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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