2013-03-22 2 views
1

나는 부모 클래스는 GameView (참고 엠)이다 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); 
    } 

     } 

라는 클래스에이 코드가 있습니다.

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

여기에 두 개의 스레드, GameView를 실행하고 서피스 뷰 SurfaceView를 소유하고있는 UI 스레드있다 :
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(); 
     } 
    } 
. . . 

나는이 예외가 , 및 GameLoop은 Thread의 확장이며 update-draw 루프 만 실행합니다.

내가 이해하는 한, UI 스레드 만 TextView tv_announcement을 만질 수 있다는 예외는 예외입니다.
UI 스레드에서 실행중인 announce이 아닙니까? 내가 여기서 무엇을 놓치고 있니? 도면 계층이 보기 터치 생성

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 me 코드를 만들 수 있습니까? – Sajmon

+0

'announce '메소드는 어디에서 호출합니까? UI 스레드에서 호출하는지 확인하십시오. – fiddler

+0

@sajmon 아마도 나는 분명하지 않았습니다. 수동으로 스레드를 만들지 않습니다. UI 스레드는 활동 스레드이고, GameLoop은 스레드를 확장하기 때문에 스레드입니다. GameLoop은 GameView 생성자에서 생성 된 GameView의 비공개 클래스입니다. – ilomambo

답변

2

은 원래의 스레드 : 여기

후 발표 예외의 로그 캣이다.

UI 스레드가 아마도 Worker Thread에서 UI를 수정하지 않으므로 오류가 발생합니다. 당신이 스레드 또는 단지 스레드에서 수행 일부 공정에서 수행 동작에서 몇 가지 정보와 UI를 업데이트하려면

만 사용할 수 있습니다

+0

예, 루프를 실행하기 위해 핸들러를 사용하려고 시도했는데 'announce'에 의해 예외가 발생하지 않았습니다. 왜 그걸 설명 할 수 있니? 내 코드에서 GameView가 Worker 스레드로 간주됩니까? (GameView는 Activity XML 레이아웃에서 인스턴스화됩니다.) – ilomambo

+0

@ilomambo이 "annouce"의 logcat이 필요합니다. – Sajmon

+0

질문에 logcat 오류가 있습니다. – ilomambo

관련 문제