2011-08-20 56 views
0

首先,請注意LunarLander示例中發生的情況完全相同。 無論如何,這個工程很好,直到我離開應用程序並嘗試返回它,於是我得到一個強制關閉(IllegalThreadStateException)。強制關閉使用SurfaceView恢復應用程序

MainGameActivity:

package com.tests.testgame1; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 

public class MainGameActivity extends Activity { 

    private static MainGameView mainGameView; 
    //private static Thread mainGameThread; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     mainGameView = new MainGameView(getApplicationContext()); 
     //mainGameThread = mainGameView.getThread(); 


//  if (savedInstanceState == null) { 
//   // we were just launched: set up a new game 
//   mainGameThread.setState(mainGameThread.STATE_READY); 
//   Log.w(this.getClass().getName(), "SIS is null"); 
//  } else { 
//   // we are being restored: resume a previous game 
//   mainGameThread.restoreState(savedInstanceState); 
//   Log.w(this.getClass().getName(), "SIS is nonnull"); 
//  } 

     setContentView(mainGameView); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     // The activity is about to become visible. 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     mainGameView.unpauseGame(); 
     // The activity has become visible (it is now "resumed"). 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     mainGameView.pauseGame(); 
     // Another activity is taking focus (this activity is about to be "paused"). 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     // The activity is no longer visible (it is now "stopped") 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     // The activity is about to be destroyed. 
    } 





    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     // just have the View's thread save its state into our Bundle 
     super.onSaveInstanceState(outState); 
//  mainGameThread.saveState(outState); 
     Log.w(this.getClass().getName(), "SIS called"); 
    } 

} 

MainGameView:

package com.tests.testgame1; 



import android.content.Context; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceHolder.Callback; 
import android.view.SurfaceView; 


public class MainGameView extends SurfaceView implements SurfaceHolder.Callback { 

    private static final String TAG = "MainGameView"; // 
    MainGameThread mainGameThread; // 
    SurfaceHolder mainSurfaceHolder; 
    Context mainContext; 

    public MainGameView(Context context) { 
     super(context); 
     mainSurfaceHolder = getHolder(); 
     mainSurfaceHolder.addCallback(this); 
     mainContext = context; 
     mainGameThread = new MainGameThread(this, mainSurfaceHolder, mainContext); 



     Log.d(TAG, "View created"); 



    } 

    public Thread getThread() { 
     return mainGameThread; 
    } 

    public void pauseGame() { 
     mainGameThread.pauseGame(); 
    } 


    public void unpauseGame() { 
     //mainGameThread.start(); 
     mainGameThread.unpauseGame(); 
    } 
    // 



    @Override 
    public void onWindowFocusChanged(boolean hasWindowFocus) { 
     if (!hasWindowFocus) mainGameThread.pauseGame(); 
    } 


    public void onDraw() 
    { 

    } 

    @Override 
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void surfaceCreated(SurfaceHolder arg0) { 

     mainGameThread.setRunning(true); 
     mainGameThread.start(); 

    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder arg0) { 

     // we have to tell thread to shut down & wait for it to finish, or else 
     // it might touch the Surface after we return and explode 
     boolean retry = true; 
     mainGameThread.setRunning(false); 
     while (retry) { 
      try { 
       mainGameThread.join(); 
       retry = false; 
      } catch (InterruptedException e) { 
      } 
     } 

    } 

} 

MainGameThread:

package com.tests.testgame1; 

import android.content.Context; 
import android.content.res.Resources; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.View; 

class MainGameThread extends Thread { 

    enum GameStates 
    { 
     GameStateRunning, 
     GameStatePaused 
    } 

    private boolean running; 
    private GameStates gameMode; 
    private View view; 
    private Context context; 
    private SurfaceHolder surfaceHolder; 

    Bitmap backgroundImage; 

    public MainGameThread(View _view, SurfaceHolder _surfaceHolder, Context _context) 
    { 
     this.view = _view; 
     this.surfaceHolder = _surfaceHolder; 
     this.context = _context; 
     this.running = true; 
     this.gameMode = GameStates.GameStateRunning; 

     Resources res = context.getResources(); 
     backgroundImage = BitmapFactory.decodeResource(res, R.drawable.background); 
    } 
    public void setRunning(boolean b) { 
     running = b; 
    } 

    @Override 
    public void run() { 


     while (running) { 
      if (gameMode == GameStates.GameStateRunning) 
        doStep(); 

      Canvas c = null; 
      try { 
       c = surfaceHolder.lockCanvas(null); 
       synchronized (surfaceHolder) { 

        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) { 
        synchronized (surfaceHolder) { 
        surfaceHolder.unlockCanvasAndPost(c); 
        } 
       } 
      } 

     } 


    } 

    private void doDraw(Canvas canvas) { 
     canvas.drawBitmap(backgroundImage, 0, 0, null); 
     //canvas.drawColor(Color.BLUE); 

    } 

    private void doStep() { 

    } 

    public void pauseGame() 
    { // 
     synchronized (surfaceHolder) { 
      if (gameMode == GameStates.GameStateRunning){ 
       gameMode = GameStates.GameStatePaused; 
      } 

     } 
    } 

    public void unpauseGame() { 
     synchronized (surfaceHolder) { 
      if (gameMode == GameStates.GameStatePaused){ 
       gameMode = GameStates.GameStateRunning; 
      } 

     } 
    } 


} 

堆棧跟蹤:

Test Game [Android Application] 
    DalvikVM[localhost:8625]  
     Thread [<1> main] (Suspended (exception IllegalThreadStateException)) 
      MainGameView(SurfaceView).updateWindow(boolean) line: 545 
      MainGameView(SurfaceView).onWindowVisibilityChanged(int) line: 206 
      MainGameView(View).dispatchWindowVisibilityChanged(int) line: 3891 
      FrameLayout(ViewGroup).dispatchWindowVisibilityChanged(int) line: 719 
      LinearLayout(ViewGroup).dispatchWindowVisibilityChanged(int) line: 719 
      PhoneWindow$DecorView(ViewGroup).dispatchWindowVisibilityChanged(int) line: 719 
      ViewRoot.performTraversals() line: 744 
      ViewRoot.handleMessage(Message) line: 1727 
      ViewRoot(Handler).dispatchMessage(Message) line: 99 
      Looper.loop() line: 123 
      ActivityThread.main(String[]) line: 4627  
      Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method] 
      Method.invoke(Object, Object...) line: 521 
      ZygoteInit$MethodAndArgsCaller.run() line: 868 
      ZygoteInit.main(String[]) line: 626 
      NativeStart.main(String[]) line: not available [native method] 
     Thread [<6> Binder Thread #2] (Running) 
     Thread [<5> Binder Thread #1] (Running) 
     Thread [<7> Binder Thread #3] (Running) 

回答

4

認爲您的SurfaceCreated方法存在問題。當你退出線程時,它將被終止。一旦發生這種情況,您不能撥打

mainGameThread.start();

相反,內surfaceCreated,首先查詢線程的狀態,再如果它已被終止,因爲你在做MainGameView開始一個新的,

if (mainGameThread .getState() == Thread.State.TERMINATED) 
{ 

    mainGameThread = new MainGameThread(this, mainSurfaceHolder, mainContext); 
    mainGameThread.setRunning(true); 
    mainGameThread.start(); 
} 
else 
{ 
    mainGameThread.setRunning(true); 
    mainGameThread.start(); 
} 
+0

_Yes_!這現在完美。非常感謝你! – Dataflashsabot

+0

不用擔心,高興可以幫忙! – Steven