Problem bei Thread beenden und aufrufen einer Activity

  • Antworten:0
Bob Kelzo
  • Forum-Beiträge: 32

06.09.2013, 02:34:35 via Website

Hallo Leute,

ich habe für ein kleines Spiel eine Surface View erstellt. Ist das Spiel zu Ende, soll eine neue Activity aufgerufen werden. Mein erstes Problem ist, dass ich in circa 70% der Fälle die Fehlermeldung "Unfortunately, Pong has stopped." bekomme, bevor die neue Activity aufgerufen wird. Die Logcatmeldung dabei sieht so aus:

FATAL EXCEPTION: Thread-75
java.lang.NullPointerException
at com.example.pong.GameView.onDraw(GameView.java:75)
at com.example.pong.GameThread.run(GameThread.java:26)

Ich kann mir nur leider nicht erklären wo der Fehler liegt, vor allem da es ja ab und zu auch funktioniert.


Mein zweites Problem ist, dass die neu aufgerufene Activity (wird auch nach der Fehlermeldung aufgerufen), gefühlt 100 mal aufgerufen wird. Heißt ich muss den Beenden-Button ziemlich oft anklicken, bis sich die App endlich schließt.

Wäre nett wenn mir einer von euch helfen könnte, ich such den Fehler seit ner Ewigkeit, finde ihn aber nicht. Ich weiß, ist zwar ne Menge Quelltext, aber ich weiß mir anders sonst nicht zu helfen.


Ich poste hier mal die Quelltextausschnitte, die ich für relevant halte.


Auszug GameView.java:
1public class GameView extends SurfaceView {
2
3 private GameThread gameThread;
4 private Bitmap bitmap;
5 private SurfaceHolder surfaceHolder;
6 private Canvas canvas;
7 private BalkenSprite spielerBalken;
8 private BalkenSprite gegnerBalken;
9 private BallSprite ballSprite;
10 private float density;
11 private int punkte;
12 private String punkteString;
13 private boolean daneben;
14 private MainActivity main = new MainActivity();
15 private boolean retry = true;
16
17
18 public GameView(Context context) {
19 super(context);
20 gameThread = new GameThread(this);
21 surfaceHolder = getHolder();
22 surfaceHolder.addCallback(new SurfaceHolder.Callback() {
23
24 @Override
25 public void surfaceDestroyed(SurfaceHolder arg0) {
26 //boolean retry = true;
27 gameThread.setRunning(false);
28 while(retry) {
29 try {
30 gameThread.join();
31 retry = false;
32 }
33 catch (InterruptedException e) {
34
35 }
36
37 }
38 }
39
40 @Override
41 public void surfaceCreated(SurfaceHolder arg0) {
42 gameThread.setRunning(true);
43 gameThread.start();
44
45 }
46
47 @Override
48 public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
49 int arg3) {
50 // TODO Auto-generated method stub
51
52 }
53 });
54 spielerBalken = new BalkenSprite(this);
55 gegnerBalken = new BalkenSprite(this);
56 ballSprite = new BallSprite(this);
57 System.out.println("width/2: " + getWidth() / 2);
58 daneben = false;
59 main = (MainActivity) context;
60 }
61
62 public void onDraw(Canvas canvas) {
63 canvas.drawColor(Color.BLACK);
64 spielerBalken.onDraw(canvas);
65 gegnerBalken.setY(ballSprite.getY());
66 gegnerBalken.onDraw(canvas);
67 gegnerBalken.setX(getWidth() - 60);
68 ballSprite.onDraw(canvas);
69
70 /** Punktestand anzeigen */
71 int fontSize = 30;
72 int yTextPos = getResources().getDisplayMetrics().heightPixels / 20;
73 Typeface font = Typeface.create("Arial", Typeface.NORMAL);
74
75 Paint paint = new Paint();
76 paint.setColor(Color.WHITE);
77 paint.setTypeface(font);
78 paint.setTextSize(fontSize);
79 paint.setAntiAlias(true);
80 punkteString = String.valueOf(ballSprite.getTreffer());
81 int x = (int) (getResources().getDisplayMetrics().widthPixels / 1.6);
82 canvas.drawText(punkteString, x, yTextPos, paint);
83
84 pruefeTreffer();
85
86 if (daneben) {
87 main.gameOver();
88 return;
89 }
90
91 abprallen();
92 }
93
94 @Override
95 public boolean onTouchEvent(MotionEvent event) {
96 if (event.getAction() == MotionEvent.ACTION_DOWN) {
97 spielerBalken.obBeruehrt((int) event.getX(), (int) event.getY());
98 }
99
100 if (event.getAction() == MotionEvent.ACTION_MOVE) {
101 // if(spielerBalken.getTouched()) {
102 spielerBalken.setY((int) event.getY() - (spielerBalken.getHoehe() / 2));
103 }
104 // }
105
106 if (event.getAction() == MotionEvent.ACTION_UP) {
107 if (spielerBalken.getTouched()) {
108 spielerBalken.setTouched(false);
109 }
110 }
111 return true;
112 }
113
114 public void pruefeTreffer() {
115 if (ballSprite.getX() <= spielerBalken.getX() + spielerBalken.getBreite() && (ballSprite.getY() + ballSprite.getHoehe() < spielerBalken.getY() || ballSprite.getY() >spielerBalken.getY() + spielerBalken.getHoehe())) {
116 ballSprite.setxSpeed(0);
117 ballSprite.setySpeed(0);
118 daneben = true;
119 // aufrufen des GameOver-Screens
120 //main.gameOver();
121 }
122 }



GameThread:
1package com.example.pong;
2
3import android.graphics.Canvas;
4
5public class GameThread extends Thread {
6
7
8 private boolean isRunning=false;
9 private Canvas canvas;
10 private GameView gameView;
11
12
13
14 public GameThread(GameView gameView) {
15 this.gameView = gameView;
16 }
17
18
19
20 public synchronized void run() {
21 while(isRunning) {
22 Canvas canvas = null;
23 try {
24 canvas = gameView.getHolder().lockCanvas();
25 synchronized (gameView.getHolder()) {
26 gameView.onDraw(canvas);
27 }
28 }
29 finally {
30 if (canvas != null) {
31 gameView.getHolder().unlockCanvasAndPost(canvas);
32 }
33 }
34 }
35 }
36
37
38
39 public void setRunning(boolean isRunning) {
40 this.isRunning = isRunning;
41 }
42
43
44
45
46}


GameoverActivity:
1package com.example.pong;
2
3import android.app.Activity;
4import android.content.Intent;
5import android.os.Bundle;
6import android.view.View;
7import android.view.View.OnClickListener;
8import android.widget.Button;
9
10public class GameoverActivity extends Activity {
11
12 @Override
13 protected void onCreate(Bundle savedInstanceState) {
14 super.onCreate(savedInstanceState);
15 setContentView(R.layout.gameover_activity);
16
17 Button button = (Button) findViewById(R.id.neustartButton);
18 button.setOnClickListener(new OnClickListener() {
19 public void onClick(View v) {
20 Intent intent = new Intent(GameoverActivity.this, MainActivity.class);
21 startActivity(intent);
22 finish();
23 }
24 });
25
26 Button button2 = (Button) findViewById(R.id.beendenButton);
27 button2.setOnClickListener(new OnClickListener() {
28 public void onClick(View v) {
29 finish();
30 }
31 });
32 } // Ende onCreate
33}


Auszug MainActivity:
1public void gameOver() {
2 Intent intent = new Intent(getApplicationContext(), GameoverActivity.class);
3 startActivity(intent);
4 this.finish();
5 }

Antworten