2017-02-07 115 views
0

我正在爲android做一個遊戲,當我退出遊戲並重新啓動遊戲時,我遇到了一些與我的線程有關的問題。我試圖中斷MainActivity中的onPause函數中的線程,並通過notify在gamepanel中的start函數中恢復線程。它有時可以工作,但並不是真正暫停遊戲。Android線程活動生命週期

在暫停一個線程的同時實現活動生命週期的正確方法是什麼?特別是一個遊戲線程,在用戶離開時不應該調用遊戲更新功能。

public class MainActivity extends Activity { 

private GamePanel gamepanel; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
    //removes title 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    //full screen 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    gamepanel = new GamePanel(this); 

    setContentView(gamepanel); 

    SoundHandler.setContext(this); 

} 

@Override 
protected void onPause() { 
    super.onPause(); 
    gamepanel.getThread().interrupt(); 

} 

@Override 
protected void onStop() { 
    super.onStop(); 
} 


@Override 
protected void onRestart() { 
    super.onRestart(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
} 


@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    boolean retry = true; 
    while (retry) { 
     try { 
      gamepanel.getThread().setRunning(false); 
      gamepanel.getThread().join(); 

     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     retry = false; 
    } 
} 
} 

的GamePanel延伸surfaceView:

@Override 
public void surfaceDestroyed (SurfaceHolder holder){} 

/**create surface. 
* 
* @param holder 
*/ 
@Override 
public void surfaceCreated (SurfaceHolder holder){ 
    //we can safely start the game loop 
    System.out.println("CREATING SURFACE"); 
    loadingscreen = false; 
    start(); 
} 

public void start() { 
    if(!mGameIsRunning) { 
     thread.start(); 
     thread.setRunning(true); 
     mGameIsRunning = true; 
    } else { 
     thread.onResume(); 
    } 
} 

Thread類

public class MainThread extends Thread { 
private SurfaceHolder surfaceHolder; 
private GamePanel gamePanel; 
public boolean running = false; 
public static Canvas canvas; 
private long startTime; 
private long fps = 1/30; 

public MainThread(SurfaceHolder surfaceHolder, GamePanel gamePanel) { 
    super(); 
    this.surfaceHolder = surfaceHolder; 
    this.gamePanel = gamePanel; 
    startTime = System.nanoTime(); 
} 

@Override 
public void run() 
{ 
    while(running) { 
     if((System.nanoTime() - startTime)/1000000000> fps) { 
      canvas = null; 
      //try locking the canvas for pixel editing 
      try { 
       canvas = surfaceHolder.lockCanvas(); 
       synchronized (surfaceHolder) { 

        this.gamePanel.update(); 
        this.gamePanel.draw(canvas); 
        this.gamePanel.checkSpeed(); 

       } 
      } catch (Exception e) { 
      } finally { 
       if (canvas != null) { 
        try { 
         surfaceHolder.unlockCanvasAndPost(canvas); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      } 

     } 
    } 

    gamePanel.surfaceDestroyed(surfaceHolder); 
} 

public void onResume(){ 
    synchronized(this){ 
     this.notify(); 
    } 
} 

public void setRunning(boolean b) 
{ 
    running=b; 
} 
public boolean getRunning(){ 
    return running; 
} 
} 
+0

您是否需要遊戲線程? – weston

+0

通過加入onPause中的線程並在onResume中創建一個新線程來修復它。 – henkaap

+0

然後發佈答案。希望你已經帶上了我的機會。 – weston

回答

0

周圍有boolean running沒有記憶障礙,你可以synchronize或使用private volatile boolean running;。那麼你需要在某處撥打setRunning(false)來阻止它,而你似乎沒有這樣做。這些原因可能是你的線程沒有退出的原因。

但我不相信在任何一個單獨的線程中呈現遊戲是沒有任何意義的。如果無法更新&超快速(例如1/60秒或更好),那麼將其移動到線程將無濟於事。