2013-03-22 18 views
1

我有這樣的代碼在名爲GameLoop(代碼類似於LunarLander樣品)哪一個是創建該視圖的原始線程?

while(running) { 
    Canvas canvas = null; 
    try { 
     canvas = mSurfaceHolder.lockCanvas(null); 
     long t = System.currentTimeMillis(); 
     if(t - old[0] >= frame) { 
      old[0] = t; 
      synchronized(mSurfaceHolder) { 
       mGame.update(); 
       mGame.onDraw(canvas); 
      } 
     } 
    } 
    finally { 
     // Do this in finally so that if an exception is thrown 
     // we don't leave the Surface in an inconsistent state 
     if(canvas != null) mSurfaceHolder.unlockCanvasAndPost(canvas); 
    } 

     } 

類的父類是GameView(參考MGAME)。
mGame.update()嘗試撥打自己的announce方法,

public class GameView extends SurfaceView implements SurfaceHolder.Callback { 

. . . 
    private void announce(int resId) { 
     synchronized(mSurfaceHolder) { 
      tv_announcement.setText(getContext().getString(resId)); 
      ObjectAnimator anim = ObjectAnimator.ofFloat(tv_announcement, "alpha", 0, 1); 
      anim.setDuration(ANNOUNCE_DURATION).start(); 
     } 
    } 
. . . 

我得到這個異常:

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

有兩個線程在這裏,UI線程,運行GameView並擁有SurfaceView ,和GameLoop這是Thread的擴展,只運行update-draw循環。

據我所知,例外是告訴我,只有UI線程可以觸摸TextView tv_announcement
但是不是announce在UI線程中運行?我在這裏錯過了什麼?

這裏是例外的logcat的宣佈後:

03-22 07:20:19.096: D/GameView(28250): + update(): state:IDLE, next state:CHOOSE_SIDE 
03-22 07:20:19.096: D/GameView(28250): + announce(resId:2131361803) 
03-22 07:20:19.096: W/dalvikvm(28250): threadid=10: thread exiting with uncaught exception (group=0xb3040180) 
03-22 07:20:19.096: E/AndroidRuntime(28250): FATAL EXCEPTION: Thread-192 
03-22 07:20:19.096: E/AndroidRuntime(28250): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4039) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:709) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.view.View.requestLayout(View.java:12675) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.view.View.requestLayout(View.java:12675) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.view.View.requestLayout(View.java:12675) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.view.View.requestLayout(View.java:12675) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.view.View.requestLayout(View.java:12675) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:268) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.view.View.requestLayout(View.java:12675) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.widget.TextView.checkForRelayout(TextView.java:6773) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.widget.TextView.setText(TextView.java:3306) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.widget.TextView.setText(TextView.java:3162) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at android.widget.TextView.setText(TextView.java:3137) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at <package>.GameView.announce(GameView.java:436) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at <package>.GameView.update(GameView.java:314) 
03-22 07:20:19.096: E/AndroidRuntime(28250): at <package>.GameView$GameLoop.run(GameView.java:495) 
03-22 07:20:19.126: D/GameView(28250): + onWindowFocusChanged(hasWindowFocus:true) 
03-22 07:20:19.126: D/GameView(28250): - onWindowFocusChanged() 
+0

你如何創建thread.give我的代碼。 – Sajmon 2013-03-22 09:19:53

+0

你在哪裏調用'announce'方法?只要確保你從UI線程調用它。 – fiddler 2013-03-22 09:31:08

+0

@sajmon我可能不是很清楚。我不手動創建線程。 UI線程是Activity線程,GameLoop是一個線程,因爲它擴展了Thread。 GameLoop是在GameView構造函數上創建的GameView的私有類。 – ilomambo 2013-03-22 11:53:17

回答

2

只有創建視圖層次可以觸摸它 享有原來的線程。

你的錯誤被拋出,因爲肯定你正在從工作線程修改UI線程。

如果您想更新與操作線程或只是在線程執行的一些過程進行一些信息的用戶界面,你只能使用:

+0

是的,我試圖使用一個處理程序來運行循環,然後沒有''通知'拋出異常。你能解釋一下爲什麼? GameView是否在我的代碼中被認爲是一個工作者線程? (GameView剛剛在活動XML佈局中實例化) – ilomambo 2013-03-22 12:06:47

+0

@ilomambo我需要logcat這個「annouce」 – Sajmon 2013-03-22 12:10:19

+0

我把logcat錯誤放在問題上。 – ilomambo 2013-03-22 12:23:08

相關問題