2015-10-02 72 views
0

我正在使用Open GL與圖形進行簡單的遊戲。我希望這樣,當某個事件發生時,玩家獲得一個點,並且這會更新覆蓋GLSurfaceView的遊戲活動的textview。Android:爲什麼我必須使用runOnUIThread()在這裏?

在此先感謝!

這裏是我的代碼的相關部分:

的活動:

public class playActivity extends Activity { 

private GLSurfaceView myGLView; 
private Handler mGameHandler; 
private TextView mScoreView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    mScoreView = new TextView(this); 
    mScoreView.setTextColor(0xFF00FF00); // Green 
    string myZeroString = "0"; 
    mScoreView.setText(myZeroString); //Starting score will always be 0 

    mGameHandler = new Handler(){ 
     public void handleMessage(Message msg){ 
      if (msg.what == MyGLRenderer.GAME_SCORE_FLAG) { 
       int score = msg.arg1; 
       mScoreView.setText(Integer.toString(score)); 
      } 

     } 
    }; 

    myGLView = new MyGLSurfaceView(this); 
    setContentView(myGLView); 

    addContentView(mScoreView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); 

} 

private void updateScoreBoard(int score){ 
    mScoreView.setText(Integer.toString(score)); 
} 


class MyGLSurfaceView extends GLSurfaceView{ 

    private final MyGLRenderer myRenderer; 

    public MyGLSurfaceView(Context context){ 
     super(context); 

     // Create an OpenGL ES 2.0 context 
     setEGLContextClientVersion(2); 

     myRenderer = new MyGLRenderer(context); 
     myRenderer.initiateHandler(mGameHandler); 

     // Set the Renderer for drawing on the GLSurfaceView 
     setRenderer(myRenderer); 

     setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); 
    } 


    } 

} 

而且GlSurfaceView.Renderer:

public class MyGLRenderer implements GLSurfaceView.Renderer{ 

    public static final int GAME_SCORE_FLAG = 1; 
    private Handler mGameHandler = null; 
    private int mScore = 0; 

    public void initiateHandler(Handler handler){ 
     mGameHandler = handler; 
    } 

    ... 

    @Override 
    public void onDrawFrame(GL10 unused){ 

     if (scoreCondition){ 
      mScore += 1; 
      if (mGameHandler != null) { 
       int flag = MyGLRenderer.GAME_SCORE_FLAG; 
       mGameHandler.dispatchMessage(Message.obtain(mGameHandler, flag, 2)); 
      } 
     } 


    } 
} 

當我運行它,它給我的錯誤: 「android.view.ViewRootImpl $ CalledFromWrongThreadException:只有創建視圖層次結構的原始線程可以觸及其視圖。」

然而,在代碼的頂部塊,當我更換

int score = msg.arg1; 
mScoreView.setText(Integer.toString(score)); 

final int score = 3; 
runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     mScoreView.setText(Integer.toString(score)); 
    } 
}); 

我不再得到的錯誤和它的作品。我認爲在第一個構建中,當我調用setText時,它必須在UI線程上執行,但Android Studio認爲是不同的。任何人都可以向我解釋這個嗎?謝謝!

回答

1

變化:

mGameHandler.dispatchMessage(Message.obtain(mGameHandler, flag, 2)); 

到:

mGameHandler.sendMessage(Message.obtain(mGameHandler, flag, 2)); 

調用dispatchMessage()將導致消息被當前線程上傳遞

(這是你的情況GL線程。)
相關問題