哪一个是创建该视图的原始线程?

问题描述:

我有这样的代码在名为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

只有创建视图层次可以触摸它 享有原来的线程。

你的错误被抛出,因为肯定你正在从工作线程修改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