CalledFromWrongThreadException: Seul le thread d’origine qui a créé une hiérarchie de vues peut toucher des vues

J’ai un problème avec l’erreur suivante dans Android:

CalledFromWrongThreadException ;: Seul le thread d’origine qui a créé une hiérarchie de vues peut toucher ses vues

Cela semble se produire lorsque j’essaie de mettre à jour une Textview dans mon activité, l’appel pour mettre à jour le TextView provient de mon activité, mais j’obtiens toujours l’erreur ci-dessus.

Je l’ai comme ça:

onCreate () place les boutons et la vue du texte.

onStateChange () – un écouteur pour les notifications sur les changements d’état, lorsque celui-ci reçoit une notification si modifie le TextView pour dire un texte différent.

Lorsque je reçois une notification d’un nouveau texte, j’essaie de modifier le TextView comme suit:

((TextView)findViewById(R.id.title)).setText("Some Text"); 

Mais j’obtiens l’erreur ci-dessus.

En le googlant, il semble que je devrais utiliser un gestionnaire pour changer le TextView ou peut-être utiliser AsyncTask?

Quelqu’un pourrait-il expliquer lequel serait préférable d’utiliser et pourquoi?

EDIT: SNIPPETS DE CODE AJOUTES:


  public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); setContentView(R.layout.my); getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.my_title); ((TextView)findViewById(R.id.time)).setText("Hello Text"); findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:")); startActivity(dialIntent); dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD)); dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK)); } }); } 

 //CallBacks from running Service private final ICallDialogActivity.Stub iCallDialogActivity = new ICallDialogActivity.Stub(){ @Override public void onStateChanged(int callState) throws RemoteException { switch(callState){ case GlobalData.CALL_STATUS_IDLE: break; case GlobalData.CALL_STATUS_DISCONNECTING: byeSetup(); break; } }; 

 public void byeSetup(){ ((TextView)findViewById(R.id.time)).setText("Bye Text"); findViewById(R.id.keyboardimage).setOnClickListener(new OnClickListener() { public void onClick(View v) { //Void the Button }}); } 

    Regardez comme vous êtes sur le mauvais fil Essayez d’utiliser un gestionnaire pour mettre à jour l’interface graphique sur le bon thread. Reportez-vous à la section Gestion des opérations coûteuses dans l’ exemple de thread d’interface utilisateur de android.com. Fondamentalement, vous allez enrouler byeSetup dans un Runnable et l’invoquer avec une instance de Handler .

     Handler refresh = new Handler(Looper.getMainLooper()); refresh.post(new Runnable() { public void run() { byeSetup(); } }); 

    Développement de la réponse de willcodejavaforfood pour plus de clarté et d’implémentation …

    J’ai eu ça au travail et ci-dessous, c’est comme ça que je l’ai fait. J’exécute plusieurs threads de traitement dans un service afin que les autres solutions exécutées dans Activity ne fonctionnent pas, comme runOnUiThread (new Runnable () {} …

    Mettez-le en haut de votre classe de service afin qu’il soit accessible partout dans cette classe:

     Handler handler; 

    Mettez ceci dans votre méthode de classe onCreate ou quelque chose qui charge sur le thread principal de service

     handler= new Handler(Looper.getMainLooper()); 

    Mettez ceci à l’intérieur de votre thread supplémentaire pour “poster” le code pour qu’il s’exécute dans l’interface utilisateur ou le service (whatevers son nom):

     handler.post(new Runnable() { public void run() { playNext(); //or whatever method you want to call thats currently not working } }); 

    Pour les autres, remplacez byeSetup (); avec vos instructions ou méthodes de code. byeSetup () est un exemple de méthode. J’espère que cela vous fera gagner du temps.

    Cette méthode est juste pour les activités et est meilleure lorsque le changement implique le thread principal ( UiThread ). Utilisez-le à l’intérieur d’un autre thread pour modifier n’importe quelle vue.

     runOnUiThread(new Runnable() { @Override public void run() { // TODO your Code et_Pass.setText(""); } }); 

    Une autre approche, utilisant cette fois-ci android.os.Message

    Avoir android.os.Handler défini comme un champ dans votre activité:

     private final Handler myTextHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message ssortingngMessage) { textView.append((Ssortingng) ssortingngMessage.obj); return true; } }); 

    Puis alimentez-le de votre autre thread comme ceci:

     Message ssortingngMessage = Message.obtain(myTextHandler); ssortingngMessage.obj = "Hello!"; ssortingngMessage.sendToTarget();