Frage

Wie kann ich Anzeigen Toast Nachrichten von einem Thread?

War es hilfreich?

Lösung

Sie können es tun, indem sie ein Activity der runOnUiThread Methode von Thread Aufruf:

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

Andere Tipps

Ich mag ein Verfahren haben, in meiner Tätigkeit genannt showToast, die ich von überall anrufen kann ...

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

ich es dann rufen am häufigsten aus MyActivity auf jedem Thread wie dieser ...

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

Dies ist vergleichbar mit anderen Antworten jedoch nach neuer verfügbaren APIs aktualisiert und viel sauberer. Auch nicht annehmen, dass Sie in einer Aktivität Kontext sind.

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();
            }
        });
    }
}

Ein Ansatz, dass die Arbeiten von so ziemlich überall, von Orten, einschließlich, wo Sie haben keine Activity oder View, sind ein Handler zu dem Haupt-Thread zu greifen und zeigen den 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();
    }
  });
}

Der Vorteil dieses Ansatzes ist, dass es mit jedem Context arbeitet, einschließlich Service und Application.

Wie dieses oder diese mit einem Runnable dass zeigt die Toast. Das heißt,

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();
}

Manchmal müssen Sie Nachricht von einem anderen Thread zu UI-Thread senden. Diese Art von Szenario tritt auf, wenn Sie nicht Netzwerk / IO-Operationen auf UI-Thread ausgeführt werden.

Im Folgenden Beispiel Griffe dieses Szenario.

  1. Sie haben UI-Thread
  2. Sie haben IO-Betrieb starten und somit kann man nicht Runnable auf UI-Thread ausgeführt werden. So veröffentlichen Sie Ihre Runnable zu Handler auf HandlerThread
  3. Holen Sie sich das Ergebnis von Runnable und an UI-Thread zurückschicken und zeigen eine Toast Nachricht.

Lösung:

  1. Erstellen Sie eine HandlerThread und starten Sie es
  2. Erstellen Sie eine Handler mit Looper von HandlerThread: requestHandler
  3. Erstellen Sie einen Handler mit Looper von Haupt Thema: responseHandler und Überschreibung handleMessage Methode
  4. post eine Runnable Aufgabe auf requestHandler
  5. Innerhalb Runnable Aufgabe, Anruf sendMessage auf responseHandler
  6. Dieser sendMessage Ergebnis Aufruf von handleMessage in responseHandler.
  7. Get Attribute aus dem Message und verarbeitet es, zu aktualisieren UI

Beispielcode:

    /* 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);
    }

Nützliche Artikel:

handlerthreads-und-warum-you-sollte-sein-mit-sie-in-your-android-apps

android-Looper-Handler-handlerthread-i

  1. Get UI-Thread-Handler-Instanz und Verwendung handler.sendMessage();
  2. Anruf post() Methode handler.post();
  3. runOnUiThread()
  4. view.post()

Sie können mit Looper Toast Nachricht senden. Gehen Sie durch diese Link mehr Einzelheiten.

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();
}

und es ist in Ihrem Thread aufgerufen. Kontext kann Activity.getContext() vom Activity bekommen Sie den Toast zeigen.

Ich habe diesen Ansatz basiert auf mjaggard Antwort:

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();
        }
    });
}

Arbeitete gut für mich.

Ich traf das gleiche Problem:

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.

Bevor: onCreate Funktion

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

Nach: onCreate Funktion

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

es hat funktioniert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top