2015-06-03 88 views
1

我正在分析與James Cho's, "The Beginner's Guide to Android Game Development"相關的代碼,並且遇到了一些與我希望獲得幫助的線程相關的混淆邏輯。如果需要,我正在分析can be downloaded的完整源代碼。在Android中,何時在SurfaceView中創建的線程被破壞?

我正在尋找幫助的具體代碼如下所示。請注意,我忽略了與問題無關的代碼。

public class GameView extends SurfaceView implements Runnable { 
    private Thread gameThread; 
    public GameView(Context context, int gameWidth, int gameHeight) { 
    SurfaceHolder holder = getHolder(); 
    holder.addCallback(new SurfaceHolder.Callback() { 
     @Override 
     public void surfaceCreated(SurfaceHolder holder) { 
     initGame(); 
     } 
     @Override 
     public void surfaceChanged(omitted) {omitted} 
     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) { 
     pauseGame(); 
     } 
    }); 
    private void initGame() { 
     gameThread = new Thread(this, "Game Thread"); 
     gameThread.start(); 
    } 
    private void pauseGame() { 
     while (gameThread.isAlive()) { 
     try { 
      gameThread.join(); 
      break; 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     } 
    } 
    } 
} 

我讀到這段代碼的方式,下面的相關邏輯發生:

  1. 當應用程序第一次啓動並顯示GameView,一個新的線程對象被創建並與我們gameThread相關變量。
  2. gameThread被賦予一個名稱,然後start()版。
  3. 如果該應用失去焦點/暫停,並且gameThread正在運行,gameThread經由join()方法暫停。 *注意:我在周圍這個邏輯有點雲裏霧裏*
  4. 如果應用程序恢復對焦/重新啓動,創建一個新的線程,並分配給我們的gameThread變量。

我閱讀這個邏輯最初的反應是,「我們爲什麼要創建一個新的線程並將其分配給gameThread?應該不是之前創建的線程還存在嗎?」我做了一些調試/日誌,並在遊戲之間的某一點發現被暫停後重新啓動,gameThread主題是「破壞」,因爲如果我嘗試過程中創建並分配initGame()之前,新的線程,我得到對gameThread一個.getName()通話空指針異常。如果現有的gameThread在暫停和恢復之間被破壞,是否不會消除與該線程關聯的任何遊戲狀態?

有人能走我走過的應用程序有失重點會發生什麼變化線程,然後恢復它(或指向我,做了資源)?

回答

0

它通常是暫停或停止線程onPause(),使它們不要繼續,而應用程序已停止或處於不同的活動來運行一個好主意。這個例子是依靠surfaceDestroyed()來暫停遊戲,這是不夠的,因爲如果用戶點擊電源按鈕以使顯示屏消隱,表面可能不會被破壞。 (注意我沒有超出你發佈的內容,所以我不知道原始代碼是否在onPause()中做了其他事情 - 如果它暫停了線程活動,那麼它就好了。)

this article中詳細介紹了SurfaceView和Activity生命週期。假設有一些熟悉Activity lifecycle

您所包含的pauseGame()方法正在調用Thread.join(),它將等待直到目標線程退出。 (它可能很早就會出現例外情況,這很可能是爲什麼它被包裹在一個「while」循環中)。因此,在pauseGame()返回時,可以確保另一個線程不再運行。您沒有包含的其他代碼必須要求該線程停止。