Question

my application crashes when i'm clicking home button or when when screen orientation is changing i've tried many solutions, but none of them worked. i've figured out that it may be connected with terminating Threads but im new in programming so i would appreciate any help. Here's code and logcat. Code is quite chaotic because i've tried implementing solutions from this and other forums

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getActionBar().hide();
    setContentView(new GameView(this));
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);     
}

}`

public class GameView extends SurfaceView implements
            SurfaceHolder.Callback {


p   private KulaSprite kula;
private PaletkaSprite paletka;
private PaletkaSprite paletka2;
private GameLogic mGameLogic;
private boolean mGameIsRunning = false;
private int punkty = 0;
private String p1 = Integer.toString(punkty);
private int punkty2 = 0;
private String p2 = Integer.toString(punkty2);
private float speed;
Paint paint = new Paint();

public void start() {
    if (!mGameIsRunning) {
        mGameLogic.setGameState(GameLogic.RUNNING);
        mGameLogic.start();
        mGameIsRunning = true;
    } else {
        mGameLogic.onResume();
    }
}


    public GameView(Context context) {
        super(context);

        setFocusable(true);
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int width = size.x;
        int height = size.y;
        kula = new KulaSprite(BitmapFactory.decodeResource(getResources(), R.drawable.kula), 600,300);
        paletka = new PaletkaSprite(BitmapFactory.decodeResource(getResources(), R.drawable.paletka),15,height/2);
        paletka2 = new PaletkaSprite(BitmapFactory.decodeResource(getResources(), R.drawable.paletka2), width-15,height/2);
        mGameLogic = new GameLogic(getHolder(), this);
        getHolder().addCallback(this);
    }

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){ 
}

    @Override
    public void surfaceCreated(SurfaceHolder holder){
        start();
    }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder){
    }

public void onDraw(Canvas canvas) {
        canvas.drawColor(Color.rgb(00, 60, 10));
        paint.setTextSize((getHeight()*2)/3);
        paint.setColor(Color.rgb(00, 80, 10));
        canvas.drawText(p1, getWidth()/12, (getHeight()*3)/4,paint);
        canvas.drawText(p2, getWidth()/2, (getHeight()*3)/4,paint);
        kula.draw(canvas);
        paletka.draw(canvas);
        paletka2.draw(canvas);


    }




public class GameLogic extends Thread {

private SurfaceHolder _surfaceHolder;
private GameView mGameView;
private int game_state;
public static final int PAUSE = 0;
public static final int READY = 1;
public static final int RUNNING = 2;
private Object mPauseLock = new Object();  
private boolean mPaused;


public GameLogic(SurfaceHolder surfaceHolder, GameView mGameView) {
    super();
    this._surfaceHolder = surfaceHolder;
    this.mGameView = mGameView;
}



public void setGameState(int gamestate) {
    this.game_state = gamestate;
}

public int getGameState(){
    return game_state;
}

public void onPause() {
    synchronized (mPauseLock) {
        mPaused = true;
    }
}

public void onResume() {
    synchronized (mPauseLock) {
        mPaused = false;
        mPauseLock.notifyAll();
    }
}

@Override
public void run() {

    Canvas canvas;
    canvas = null;

    while (game_state == RUNNING) {


        try {
                canvas = this._surfaceHolder.lockCanvas(null);
                synchronized (_surfaceHolder) {
                    this.mGameView.update();
                    this.mGameView.onDraw(canvas);

                }
        }

        finally {
                    if (canvas != null) {
                        _surfaceHolder.unlockCanvasAndPost(canvas);
                    }
        }
        synchronized (mPauseLock) {
            while (mPaused) {
                try {
                    mPauseLock.wait();
                } catch (InterruptedException e) {
                }
            }
        }
    }
}

}

03-30 14:19:24.880: D/libEGL(3010): loaded /system/lib/egl/libEGL_tegra.so
03-30 14:19:24.910: D/libEGL(3010): loaded /system/lib/egl/libGLESv1_CM_tegra.so
03-30 14:19:24.920: D/libEGL(3010): loaded /system/lib/egl/libGLESv2_tegra.so
03-30 14:19:24.960: D/OpenGLRenderer(3010): Enabling debug mode 0
03-30 14:19:29.270: W/dalvikvm(3010): threadid=11: thread exiting with uncaught         exception (group=0x41703ba8)
03-30 14:19:29.270: E/AndroidRuntime(3010): FATAL EXCEPTION: Thread-2715
03-30 14:19:29.270: E/AndroidRuntime(3010): Process: com.pingpong, PID:  3010
03-30 14:19:29.270: E/AndroidRuntime(3010): java.lang.NullPointerException
03-30 14:19:29.270: E/AndroidRuntime(3010):     at       com.GameView.onDraw(GameView.java:88)
03-30 14:19:29.270: E/AndroidRuntime(3010):     at   com.pingpong.GameLogic.run(GameLogic.java:60)
Was it helpful?

Solution

Pressing the back button or rotating your device will cause the activity to recreate itself. Since you are making a game, lock the screen into the desired orientation from the AndroidManifest file for that activity so orientation changes won't trigger it. http://developer.android.com/guide/topics/manifest/activity-element.html

To handle the user exiting (back press or home press) you need to override onPause() or onStop() in the activity and stop your game loop from executing. Since they are in separate threads, the loop will continue to execute whether you are in the activity or not.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top