web-dev-qa-db-fra.com

Android: Toast dans un fil

Comment puis-je afficher Toast les messages d'un fil? 

101
Arutha

Vous pouvez le faire en appelant la méthode Activity d'une runOnUiThread depuis votre thread:

activity.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
    }
});
233
Lauri Lehtinen

J'aime avoir dans mon activité une méthode appelée showToast que je peux appeler de n'importe où ...

public void showToast(final String toast)
{
    runOnUiThread(() -> Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show());
}

Je l’appelle le plus souvent de MyActivity dans un fil comme celui-ci ...

showToast(getString(R.string.MyMessage));
58
mjaggard

Ceci est similaire aux autres réponses, cependant mis à jour pour les nouveaux API disponibles et beaucoup plus propres. En outre, ne supposez pas que vous êtes dans un contexte d'activité.

public class MyService extends AnyContextSubclass {

    public void postToastMessage(final String message) {
        Handler handler = new Handler(Looper.getMainLooper());

        handler.post(new Runnable() {

            @Override
            public void run() {
                Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
            }
        });
    }
}
25
ChrisCM

Comme ceci ou ceci , avec une Runnable qui montre la Toast. À savoir,

Activity activity = // reference to an Activity
// or
View view = // reference to a View

activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        showToast(activity);
    }
});
// or
view.post(new Runnable() {
    @Override
    public void run() {
        showToast(view.getContext());
    }
});

private void showToast(Context ctx) {
    Toast.makeText(ctx, "Hi!", Toast.LENGTH_SHORT).show();
}
10
yanchenko

Une approche qui fonctionne à peu près n'importe où, y compris dans les endroits où vous n'avez pas de Activity ou View, consiste à saisir Handler au fil principal et à afficher le pain grillé:

public void toast(final Context context, final String text) {
  Handler handler = new Handler(Looper.getMainLooper());
  handler.post(new Runnable() {
    public void run() {
      Toast.makeText(context, text, Toast.DURATION_LONG).show();
    }
  });
}

L’avantage de cette approche est qu’elle fonctionne avec toute variable Context, y compris Service et Application

8
Mike Laren

Parfois, vous devez envoyer un message d'une autre Thread au thread d'interface utilisateur. Ce type de scénario se produit lorsque vous ne pouvez pas exécuter d'opérations réseau/ES sur le thread d'interface utilisateur. 

L'exemple ci-dessous gère ce scénario.

  1. Vous avez un fil d'interface utilisateur
  2. Vous devez commencer l'opération IO et par conséquent vous ne pouvez pas exécuter Runnable sur le thread d'interface utilisateur. Alors postez votre Runnable au gestionnaire sur HandlerThread
  3. Obtenez le résultat de Runnable et renvoyez-le au fil de l'interface utilisateur et affichez un message Toast.

Solution:

  1. Créez un HandlerThread et démarrez-le
  2. Créer un Handler with Looper from HandlerThread: requestHandler
  3. Créer un gestionnaire avec Looper à partir du thread principal: responseHandler et remplacer la méthode handleMessage
  4. post une Runnable tâche sur requestHandler
  5. Dans la tâche Runnable, appelez sendMessage à responseHandler
  6. Cet invocation de résultat sendMessage de handleMessage dans responseHandler.
  7. Obtenir les attributs de la Message et le traiter, mettre à jour l'interface utilisateur

Exemple de code:

    /* Handler thread */

    HandlerThread handlerThread = new HandlerThread("HandlerThread");
    handlerThread.start();
    Handler requestHandler = new Handler(handlerThread.getLooper());

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    for ( int i=0; i<5; i++) {
        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                try {

                    /* Add your business logic here and construct the 
                       Messgae which should be handled in UI thread. For 
                       example sake, just sending a simple Text here*/

                    String text = "" + (++rId);
                    Message msg = new Message();

                    msg.obj = text.toString();
                    responseHandler.sendMessage(msg);
                    System.out.println(text.toString());

                } catch (Exception err) {
                    err.printStackTrace();
                }
            }
        };
        requestHandler.post(myRunnable);
    }

Articles utiles:

handlerthreads-and-pourquoi-vous-devriez-être-en-utilisant-les-dans-vos-applications-Android

Android-looper-handler-handlerthread-i

6
Ravindra babu

Vous pouvez utiliser Looper pour envoyer un message Toast. Passez par ce lien link pour plus de détails. 

public void showToastInThread(final Context context,final String str){
    Looper.prepare();
    MessageQueue queue = Looper.myQueue();
    queue.addIdleHandler(new IdleHandler() {
         int mReqCount = 0;

         @Override
         public boolean queueIdle() {
             if (++mReqCount == 2) {
                  Looper.myLooper().quit();
                  return false;
             } else
                  return true;
         }
    });
    Toast.makeText(context, str,Toast.LENGTH_LONG).show();      
    Looper.loop();
}

et cela s'appelle dans votre fil. Le contexte peut être Activity.getContext() à partir de la Activity vous devez montrer le pain grillé.

3

J'ai fait cette approche basée sur la réponse de mjaggard:

public static void toastAnywhere(final String text) {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        public void run() {
            Toast.makeText(SuperApplication.getInstance().getApplicationContext(), text, 
                    Toast.LENGTH_LONG).show();
        }
    });
}

A bien fonctionné pour moi.

2
Ângelo Polotto

J'ai rencontré le même problème:

E/AndroidRuntime: FATAL EXCEPTION: Thread-4
              Process: com.example.languoguang.welcomeapp, PID: 4724
              Java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
                  at Android.widget.Toast$TN.<init>(Toast.Java:393)
                  at Android.widget.Toast.<init>(Toast.Java:117)
                  at Android.widget.Toast.makeText(Toast.Java:280)
                  at Android.widget.Toast.makeText(Toast.Java:270)
                  at com.example.languoguang.welcomeapp.MainActivity$1.run(MainActivity.Java:51)
                  at Java.lang.Thread.run(Thread.Java:764)
I/Process: Sending signal. PID: 4724 SIG: 9
Application terminated.

Avant: fonction onCreate

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
    }
});
thread.start();

Après: fonction onCreate

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
    }
});

ça a marché.

0
Languoguang