Android: grillé dans un thread

Comment afficher Toast messages à partir d'un thread?

98
demandé sur Ravindra babu 2010-06-28 21:31:48

10 réponses

vous pouvez le faire en appelant un Activity 's runOnUiThread méthode de votre fil:

activity.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
    }
});
228
répondu Lauri Lehtinen 2010-06-28 17:37:15

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 donc le plus souvent de l'intérieur de MyActivity sur n'importe quel fil comme celui-ci...

showToast(getString(R.string.MyMessage));
56
répondu mjaggard 2018-03-28 10:53:45

c'est similaire à d'autres réponses, cependant mis à jour pour les nouveaux API disponibles et beaucoup plus propre. En outre, ne suppose 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();
            }
        });
    }
}
24
répondu ChrisCM 2017-01-30 20:57:35

Comme ce ou ce , avec un Runnable qui montre que le 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();
}
9
répondu yanchenko 2012-05-15 01:43:47

une approche qui fonctionne à peu près n'importe où, y compris des endroits où vous n'avez pas un Activity ou View , est de saisir un Handler au fil principal et de montrer le toast:

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'il fonctionne avec n'importe quel Context , y compris Service et Application .

7
répondu Mike Laren 2018-07-10 17:56:14

parfois, vous devez envoyer un message d'un autre Thread au fil UI. Ce type de scénario se produit lorsque vous ne pouvez pas exécuter les opérations réseau/IO sur le thread UI.

ci-dessous l'exemple traite ce scénario.

  1. Vous avez Thread d'INTERFACE utilisateur
  2. vous devez démarrer L'opération IO et donc vous ne pouvez pas exécuter Runnable sur le thread UI. Alors postez votre Runnable à handler sur HandlerThread
  3. récupérez le résultat de Runnable et renvoyez-le au fil UI et affichez un message Toast .

Solution:

  1. Créer un HandlerThread et il commence
  2. créer un Handler avec Looper de HandlerThread : requestHandler
  3. créer un Handler avec Looper à partir du fil principal: responseHandler et remplacer handleMessage méthode
  4. post a Runnable tâche sur requestHandler
  5. à l'Intérieur Runnable de la tâche, de l'appeler sendMessage sur responseHandler
  6. Ce sendMessage résultat de l'invocation de la handleMessage dans responseHandler .
  7. Obtenir les attributs de la Message et de processus, mise à jour de 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-et-pourquoi-vous-devrait-être-aide-dans-votre-android-apps

android-looper-gestionnaire-handlerthread-je

6
répondu Ravindra babu 2017-08-30 07:13:44
  1. Obtenir le Thread de l'INTERFACE utilisateur du Gestionnaire d'instance et d'utilisation handler.sendMessage();
  2. Appel post() méthode handler.post();
  3. runOnUiThread()
  4. view.post()
5
répondu Kerwin You 2017-10-03 13:48:14

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
répondu Angelo Polotto 2017-12-06 18:42:16

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.run(MainActivity.java:51)
                  at java.lang.Thread.run(Thread.java:764)
I/Process: Sending signal. PID: 4724 SIG: 9
Application terminated.

Avant: fonction oncrée

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

après: fonction oncrée

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

ça a marché.

0
répondu Languoguang 2018-05-31 08:58:22