我有這樣的代碼在名爲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()
你如何創建thread.give我的代碼。 – Sajmon 2013-03-22 09:19:53
你在哪裏調用'announce'方法?只要確保你從UI線程調用它。 – fiddler 2013-03-22 09:31:08
@sajmon我可能不是很清楚。我不手動創建線程。 UI線程是Activity線程,GameLoop是一個線程,因爲它擴展了Thread。 GameLoop是在GameView構造函數上創建的GameView的私有類。 – ilomambo 2013-03-22 11:53:17