Question

Comment puis-je afficher des messages Toast à partir d'un fil?

Était-ce utile?

La solution

Vous pouvez le faire en appelant une méthode de Activity de runOnUiThread de votre fil:

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

Autres conseils

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

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

Je puis plus souvent appeler de l'intérieur MyActivity sur un fil comme celui-ci ...

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

Ceci est similaire à d'autres réponses, mais mis à jour pour les nouveaux APIs disponibles et beaucoup plus propre. En outre, ne présumez 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();
            }
        });
    }
}

Une approche qui fonctionne à peu près de partout, y compris des endroits où vous n'avez pas Activity ou View, est de saisir un Handler au fil principal et montrer 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 tout Context, y compris Service et Application.

Comme cette ou cette , avec un Runnable que montre la Toast. A 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();
}

Parfois, vous avez d'envoyer un message d'un autre Thread à fil interface utilisateur. Ce type de scénario se produit lorsque vous ne pouvez pas exécuter des opérations / réseau IO sur fil interface utilisateur.

Ci-dessous, par exemple poignées scénario.

  1. Vous avez Thread UI
  2. Vous devez commencer l'opération IO et vous pouvez donc ne pas fonctionner Runnable sur thread d'interface utilisateur. Donc publier votre Runnable au gestionnaire sur HandlerThread
  3. Obtenir le résultat de Runnable et de le renvoyer à la discussion interface utilisateur et affiche un message Toast.

Solution:

  1. Créer un HandlerThread et démarrer
  2. Créer un Handler avec Looper de HandlerThread: requestHandler
  3. Créer un gestionnaire avec Looper de thread principal: méthode responseHandler et override handleMessage
  4. post une tâche Runnable sur requestHandler
  5. intérieur tâche Runnable, sendMessage d'appel sur responseHandler
  6. Cette invocation de résultat sendMessage de handleMessage dans responseHandler.
  7. Obtenir les attributs du Message et le traiter, l'interface utilisateur de mise à jour

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-en utilisant-les-in-your-android-apps

androïde-arpenteuse-handler-handlerthread-i

  1. Obtenir l'interface utilisateur Enfilez instance gestionnaire et à l'utilisation handler.sendMessage();
  2. Appel méthode post() handler.post();
  3. runOnUiThread()
  4. view.post()

Vous pouvez utiliser Looper envoyer un message Toast. Passez par ce lien pour plus 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 il est appelé dans votre fil. Contexte peut être Activity.getContext() obtenir de l'Activity vous devez montrer le pain grillé.

J'ai fait cette approche basée sur la réponse 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.

Je rencontre 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: la fonction onCreate

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

il a travaillé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top