2010-10-23 8 views
1

Je reçois la faute "CalledFromWrongThreadException: Seul le thread d'origine qui a créé une hiérarchie de vue peut toucher ses vues."Android comment résoudre le problème en touchant une vue du mauvais fil?

Le problème provient de l'appel onDraw dans TutorialThread. Le code fonctionne si l'appel à startAnimation dans onDraw est supprimé. Pourquoi le code fonctionne-t-il si startAnimation est supprimé? Pourquoi cet appel est-il différent de l'appel à drawRect?

Voici le code:

public class GamePanel étend l'activité { Panel privé mPanel;

public void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState); 
    mPanel = new Panel(this); 
    setContentView(mPanel); 
    mPanel.requestFocus(); 
} 

}

Panel de classe étend SurfaceView implémente SurfaceHolder.Callback { TutorialThread privé _thread; Peinture privée mPaint; Contexte de contexte; jeu final privé GamePanel;

public Panel(Context context) { 
    super(context); 
    this.game = (GamePanel) context; 
    getHolder().addCallback(this); 
    _thread = new TutorialThread(getHolder(),this); 

    setFocusable(true); 
    mPaint = new Paint(); 
} 
@Override 
public void onDraw(Canvas canvas) {    
    canvas.drawARGB(255, 0, 0, 0);    
    mPaint.setColor(Color.WHITE); 
    mPaint.setStyle(Paint.Style.FILL); 
    canvas.drawRect(100, 100, 150, 150, mPaint); 
    startAnimation(AnimationUtils.loadAnimation(game,R.anim.shake)); 
}    
@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){ 

} 
@Override 
public void surfaceCreated(SurfaceHolder holder){ 
    _thread.setRunning(true); 
    _thread.start(); 
} 
@Override 
public void surfaceDestroyed(SurfaceHolder holder){ 
    boolean retry = true; 
    _thread.setRunning(false); 
    while(retry) { 
     try { 
      _thread.join(); 
      retry = false; 
     } catch(InterruptedException e) { 

     } 
    } 
} 

class TutorialThread extends Thread { 
    private SurfaceHolder _surfaceHolder; 
    private Panel _panel; 
    private boolean _run = false; 

    public TutorialThread(SurfaceHolder surfaceHolder,Panel panel){ 
     _surfaceHolder = surfaceHolder; 
     _panel = panel; 
    } 
    public void setRunning(boolean run){ 
     _run = run; 
    } 
    @Override 
    public void run(){ 
     Canvas c; 
     while(_run){ 
      c=null; 
      try{ 
       c = _surfaceHolder.lockCanvas(null); 
       synchronized(_surfaceHolder){      
        _panel.onDraw(c); 
       } 
      }finally{ 
       if(c!=null){ 
        _surfaceHolder.unlockCanvasAndPost(c); 
       } 
      } 
      try 
      { 
       Thread.sleep(500); 
      } 
       catch(InterruptedException Ie) { 
      }     
     }   
    }  
} 

}

Répondre

0

au lieu de votre classe personnalisée de fil, vous devez utiliser AsyncTask. AsyncTask permet une utilisation correcte et facile du thread UI.

Questions connexes