2012-10-30 5 views
2

작은 이미지를 화면에 표시하고 화면의 하단 50px를 탭하면 Android 앱이 만들어졌습니다. 제가 탭을 누르면 정상적으로 종료되지만, 응용 프로그램을 종료하기 위해 뒤로 (또는 집) 버튼을 누르면 종료되지만 "안타깝게도 게임 개발은 중단되었습니다."라고 말합니다. 또한 LogCat을 검사하여 작동이 멈출 때마다 Java NullPointerException이 발생했음을 보여줍니다. 로그 캣의 출력했다 : Game.java (활동), GameView.java합니다 (서피스 뷰 SurfaceView), 및 GameThread.java (메인 스레드) :뒤로 버튼을 누른 후 Android 앱이 작동하지 않음

10-30 01:13:28.280: E/AndroidRuntime(15294): FATAL EXCEPTION: Thread-1718 
10-30 01:13:28.280: E/AndroidRuntime(15294): java.lang.NullPointerException 
10-30 01:13:28.280: E/AndroidRuntime(15294): at tricrose.gamedev.GameView.onDraw(GameView.java:56) 
10-30 01:13:28.280: E/AndroidRuntime(15294): at tricrose.gamedev.GameThread.run(GameThread.java:30) 

나는 3 개 자바 클래스가 있습니다.

Game.java을 : 다음과 같이

코드는

package tricrose.gamedev; 

import android.os.Bundle; 
import android.app.Activity; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.Menu; 
import android.view.Window; 
import android.view.WindowManager; 

public class Game extends Activity { 

    public static final String TAG = Game.class.getSimpleName(); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     setContentView(new GameView(this)); 
     Log.d(TAG, "View added"); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_game, menu); 
     return true; 
    } 
} 

GameView.java :

package tricrose.gamedev; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

public class GameView extends SurfaceView implements SurfaceHolder.Callback { 

    public static final String TAG = GameView.class.getSimpleName(); 
    private GameThread thread; 

    public GameView(Context context) { 
     super(context); 
     getHolder().addCallback(this); 
     thread = new GameThread(getHolder(), this); 
     setFocusable(true); 
    } 

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

    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     thread.setRunning(true); 
     thread.start(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     boolean retry = true; 
     while (retry) { 
      try { 
       thread.join(); 
       retry = false; 
      } catch (Exception e) {} 
     } 
    } 

    public boolean onTouchEvent(MotionEvent e) { 
     if (e.getAction() == MotionEvent.ACTION_DOWN) { 
      if (e.getY() > getHeight() - 60) { 
       thread.setRunning(false); 
       ((Activity)getContext()).finish(); 
      } 
     } 
     return super.onTouchEvent(e); 
    } 

    protected void onDraw(Canvas canvas) { 
     canvas.drawColor(Color.BLACK); 
     canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.droid_1), 10, 10, null); 
    } 
} 

GameThread.java : 나는했습니다

package tricrose.gamedev; 

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

public class GameThread extends Thread { 

    public static final String TAG = GameThread.class.getSimpleName(); 
    private boolean running; 
    private SurfaceHolder surfaceHolder; 
    private GameView gameView; 

    public GameThread(SurfaceHolder surfaceHolder, GameView gameView) { 
     super(); 
     this.surfaceHolder = surfaceHolder; 
     this.gameView = gameView; 
    } 

    public void setRunning(boolean running) { 
     this.running = running; 
    } 

    public void run() { 
     Canvas canvas; 
     while (running) { 
      canvas = null; 
      try { 
       canvas = this.surfaceHolder.lockCanvas(); 
       synchronized (surfaceHolder) { 
        this.gameView.onDraw(canvas); 
       } 
      } finally { 
       if (canvas != null) { 
        surfaceHolder.unlockCanvasAndPost(canvas); 
       } 
      } 
     } 
    } 
} 

인터넷을 통해 다음과 같이 검색했습니다. olution, 그리고 실제로 작동 한 하나를 찾을 수 없습니다, 그래서 어떤 도움을 대단히 감사합니다.

답변

0

왜 당신은 onDraw와 GameThread에서 두 곳에서 그리기를하고 있습니다. onDraw를 GameThread rlun 메서드에서만 모든 드로잉을 제거해야한다고 생각합니다.

+0

저는 GameThread 클래스에서 드로잉을하고 있지만 GameThread 클래스에서 제거하면 onDraw 함수가 호출되지 않습니다. 나는 그것을 시도하고 onDraw 함수를 호출하는 GameThread의 루프이기 때문에 이미지가 나타나지 않았다. – Tristram

+0

GameThread에서 onDraw를 호출하지 마십시오. 그리기 코드를 실행하고 onDraw를 제거 할 필요가 없습니다. –

+0

onDraw 함수에 있는지 여부와 상관없이 스레드가 반복 될 때마다 동일한 코드가 호출되기 때문에 매우 좋은 생각입니다. 불행히도, 작동하지 않았습니다. – Tristram

0

이것은 추측에 불과하지만 앱이 종료되는 동안 앱이 계속 그림이 될 수 있습니다.
1 : 당신이 시도 할 수

), 당신은 더 이상 사용할 수 resuorces이 없을 수도 있습니다이 경우
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.droid_1), 10, 10, null);
: 당신에서의 onDraw 방법 당신은 (아마도 문제의 당신의 원인) 코드 줄을 호출 . 당신의 GameView 클래스에 클래스 개인 비트 맵 변수를 넣어 :
private Bitmap mBitmap;
2.로드 비트 맵을 당신의 GameView 생성자에서 :
제 (이미로드) 비트 맵을 사용하여 mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.droid_1);
3. 그리기 :
canvas.drawBitmap(mBitmap, 10, 10, null);

희망 하시겠습니까?

+0

제안 해 주셔서 감사합니다.하지만 불행히도 작동하지 않았습니다.GameView 클래스에서 비공개 비트 맵을 생성해도 여전히 동일한 오류가 발생했지만 애플리케이션이 수행 할 때 스레드가 종료되지 않으므로 NullPointerException이 발생합니다. 정말 좋은 제안입니다. – Tristram

+0

이 코드를 사용하는 것은보기 싫지만,이 문제를 해결하려면 onDraw 메소드에 다음과 같이 입력하면됩니다.'code'try {/ * 여기에 코드를 그리는 코드 * /} catch (NullPointerException e) {Log. e ("MyTAG", "NPE 무시", e);} – Peter

2

결국 솔루션을 찾을 수있었습니다! onDraw를 호출하기 전에 캔버스가 null인지 확인하고, null 인 경우 해당 작업을 완료하여 응용 프로그램을 종료해야합니다. JavaCodeGeeks.com에서 Android 튜토리얼을보고있는 솔루션을 찾았습니다. 모든 사람들의 답변에 감사드립니다.

관련 문제