Android: Toast in einem Thread


Answers

Ich mag eine Methode in meiner Aktivität namens showToast die ich von überall aufrufen kann ...

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

Ich rufe es dann am häufigsten in MyActivity auf einem beliebigen Thread an ...

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

Wie kann ich Toast Nachrichten aus einem Thread anzeigen?




Sie können Looper , um eine Toast Nachricht zu senden. Weitere Informationen erhalten Sie über diesen link .

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 heißt in deinem Thread. Kontext kann Activity.getContext() , das von der Activity Sie den Toast zeigen müssen.




Manchmal müssen Sie eine Nachricht von einem anderen Thread an den UI-Thread senden. Diese Art von Szenario tritt auf, wenn Sie Netzwerk- / IO-Vorgänge im UI-Thread nicht ausführen können.

Im folgenden Beispiel wird dieses Szenario behandelt.

  1. Sie haben UI-Thread
  2. Sie müssen die IO-Operation starten und daher können Sie Runnable für den UI-Thread nicht ausführen. Also Runnable deine Runnable zu Handler auf HandlerThread
  3. Runnable Sie das Ergebnis von Runnable und senden Sie es zurück an den UI-Thread und zeigen Sie eine Toast Nachricht an.

Lösung:

  1. Erstellen Sie einen HandlerThread und starten Sie ihn
  2. Erstellen Sie einen Handler mit Looper von HandlerThread : requestHandler
  3. Erstellen Sie einen Handler mit Looper aus dem handleMessage : responseHandler und überschreiben handleMessage Methode handleMessage
  4. eine Runnable Aufgabe auf requestHandler
  5. Innerhalb der Runnable Task rufen Sie sendMessage in responseHandler
  6. Dieser sendMessage Ergebnisaufruf von handleMessage in responseHandler .
  7. Holen Sie sich Attribute aus der Message und bearbeiten Sie sie, aktualisieren Sie die Benutzeroberfläche

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-and-why-you-should-be-using-them-in-your-android-apps

android-looper-handler-handlerthread-i




Ich stieß auf 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.

Vorher: onCreate-Funktion

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

Nachher: ​​onCreate-Funktion

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

es funktionierte.




So oder this , mit einem Runnable , das den Toast zeigt. Nämlich,

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