java.lang.RuntimeException: Impossible de créer un gestionnaire à l’intérieur du thread qui n’a pas appelé Looper.prepare ();

J’ai une application Android exécutant un thread. Je veux un message Toast avec un message.

Quand je fais cela, j’obtiens l’exception suivante:

Trace logcat :

FATAL EXCEPTION: Timer-0 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.(Handler.java:121) at android.widget.Toast$TN.(Toast.java:322) at android.widget.Toast.(Toast.java:91) at android.widget.Toast.makeText(Toast.java:238) 

Existe-t-il un moyen de transférer les messages Toast des threads vers l’interface utilisateur?

J’ai eu cette exception parce que j’essayais de créer un popup Toast à partir d’un thread d’arrière-plan.
Toast a besoin d’une activité pour accéder à l’interface utilisateur et les threads ne l’ont pas.
Une solution consiste donc à atsortingbuer au thread un lien vers l’activité parent et Toast.

Placez ce code dans le thread où vous voulez envoyer un message Toast:

 parent.runOnUiThread(new Runnable() { public void run() { Toast.makeText(parent.getBaseContext(), "Hello", Toast.LENGTH_LONG).show(); } }); 

Gardez un lien vers l’activité parent dans le thread d’arrière-plan qui a créé ce thread. Utilisez la variable parent dans votre classe de thread:

 private static YourActivity parent; 

Lorsque vous créez le thread, transmettez l’activité parent en tant que paramètre via le constructeur, comme ceci:

 public YourBackgroundThread(YourActivity parent) { this.parent = parent; } 

Maintenant, le thread d’arrière-plan peut pousser les messages Toast à l’écran.

Android fonctionne essentiellement sur deux types de thread, à savoir le thread d’interface utilisateur et le thread d’arrière-plan. Selon la documentation Android –

N’accédez pas à la boîte à outils d’interface utilisateur Android en dehors du thread d’interface utilisateur pour résoudre ce problème, Android offre plusieurs façons d’accéder au thread d’interface utilisateur à partir d’autres threads. Voici une liste de méthodes pouvant vous aider:

 Activity.runOnUiThread(Runnable) View.post(Runnable) View.postDelayed(Runnable, long) 

Maintenant, il existe différentes méthodes pour résoudre ce problème. Je vais l’expliquer par exemple de code

runOnUiThread

 new Thread() { public void run() { myactivity.this.runOnUiThread(new runnable() { public void run() { //Do your UI operations like dialog opening or Toast here } }); } }.start(); 

LOOPER

Classe utilisée pour exécuter une boucle de message pour un thread. Les threads par défaut ne sont pas associés à une boucle de message. pour en créer un, appelez prepare () dans le thread qui doit exécuter la boucle, puis loop () pour qu’il traite les messages jusqu’à ce que la boucle soit arrêtée.

 class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } 

AsyncTask

AsyncTask vous permet d’effectuer un travail asynchrone sur votre interface utilisateur. Il effectue les opérations de blocage dans un thread de travail, puis publie les résultats sur le thread d’interface utilisateur, sans que vous ayez à gérer vous-même les threads et / ou les gestionnaires.

 public void onClick(View v) { new CustomTask().execute((Void[])null); } private class CustomTask extends AsyncTask { protected Void doInBackground(Void... param) { //Do some work return null; } protected void onPostExecute(Void param) { //Print Toast or open dialog } } 

Manutentionnaire

Un gestionnaire vous permet d’envoyer et de traiter des objects Message et Runnable associés à un MessageQueue d’un thread.

 Message msg = new Message(); new Thread() { public void run() { msg.arg1=1; handler.sendMessage(msg); } }.start(); Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { if(msg.arg1==1) { //Print Toast or open dialog } return false; } }); 

Voici ce que j’ai fait:

  public void displayError(final Ssortingng errorText) { Runnable doDisplayError = new Runnable() { public void run() { Toast.makeText(getApplicationContext(), errorText, Toast.LENGTH_LONG).show(); } }; messageHandler.post(doDisplayError); } 

Cela devrait permettre d’appeler la méthode depuis l’un ou l’autre thread.

Où messageHandler est déclaré dans l’activité en tant que ..

 Handler messageHandler = new Handler(); 

De http://developer.android.com/guide/components/processes-and-threads.html :

En outre, la boîte à outils de l’interface utilisateur Android n’est pas compatible avec les threads. Donc, vous ne devez pas manipuler votre interface utilisateur à partir d’un thread de travail – vous devez effectuer toutes les manipulations sur votre interface utilisateur à partir du thread d’interface utilisateur. Ainsi, il existe simplement deux règles pour le modèle à thread unique Android:

  1. Ne bloquez pas le thread d’interface utilisateur
  2. N’accédez pas à la boîte à outils d’interface utilisateur Android en dehors du thread d’interface utilisateur

Vous devez détecter l’inactivité dans un thread de travail et afficher un toast dans le thread principal.

S’il vous plaît envoyer un code, si vous voulez une réponse plus détaillée.

Après publication du code:

Dans ssortingngs.xml

 "You are getting late do it fast" 

Dans YourWorkerThread.java

 Toast.makeText(getApplicationContext(), getSsortingng(R.ssortingng.idleness_toast), Toast.LENGTH_LONG).show(); 

N’utilisez pas AlertDialog, faites un choix. AlertDialog et Toast sont deux choses différentes.

Vous pouvez simplement utiliser BeginInvokeOnMainThread (). Il appelle une action sur le thread principal de l’interface utilisateur.

 Device.BeginInvokeOnMainThread(() => { displayToast("text to display"); }); 

C’est simple et fonctionne parfaitement pour moi!

EDIT: Fonctionne si vous utilisez C # Xamarin