Wie kann ich Toastnachrichten aus einem Thread anzeigen ?
Wie kann ich Toastnachrichten aus einem Thread anzeigen ?
Antworten:
Sie können es tun , indem sie einen Aufruf Activity‚s runOnUiThreadMethode von Thread:
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
ThreadObjektreferenz auf die Activityin den Activity's ein onResume. Deaktivieren Sie es in den Activity's onPause. Tun Sie beides unter einem synchronizedSchloss, das sowohl das Activityals auch Threadrespektiert.
ActivityInstanz. Sie können stattdessen eine einfache Hilfsklasse
MyActivity.this.runOnUiThread()innerhalb eines inneren Thread/ gut funktioniert AsyncTask.
Ich möchte eine Methode in meiner Aktivität haben, showToastdie ich von überall aus 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 von innen MyActivityin einem Thread wie diesem auf ...
showToast(getString(R.string.MyMessage));
Dies ähnelt anderen Antworten, wurde jedoch für neue verfügbare APIs und viel sauberer aktualisiert. Es wird auch nicht davon ausgegangen, dass Sie sich in einem Aktivitätskontext befinden.
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, der von nahezu jedem Ort aus funktioniert, auch von Orten, an denen Sie kein Activityoder haben View, besteht darin, einen Handlerzum Hauptfaden zu greifen und den Toast zu zeigen:
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 er mit jedem funktioniert Context, einschließlich Serviceund Application.
Wie dies oder das , mit ein , Runnabledass zeigt die Toast. 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();
}
Manchmal müssen Sie eine Nachricht von einem anderen Threadan den UI-Thread senden . Diese Art von Szenario tritt auf, wenn Sie keine Netzwerk- / E / A-Vorgänge auf dem UI-Thread ausführen können.
Das folgende Beispiel behandelt dieses Szenario.
Runnableauf dem UI-Thread ausgeführt werden. Also poste deinen RunnableHandler aufHandlerThreadRunnableund senden Sie es an den UI-Thread zurück und zeigen Sie eine ToastNachricht an.Lösung:
HandlerThread:requestHandlerresponseHandlerund überschreiben Sie die handleMessageMethodeposteine RunnableAufgabe aufrequestHandlerRunnableRufen Sie innerhalb der Aufgabe sendMessageanresponseHandlersendMessageErgebnisaufruf von handleMessagein responseHandler.Messageund verarbeiten Sie es, aktualisieren Sie die BenutzeroberflächeBeispielcode:
/* 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-du-solltest-sie-in-deinen-android-apps verwenden
handler.sendMessage();post()Methode aufrufenhandler.post();runOnUiThread()view.post() Sie können Looperzum Senden von ToastNachrichten verwenden. Gehen Sie über diesen Link für weitere Details.
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. Der Kontext kann Activity.getContext()von dem stammen, dass ActivitySie den Toast zeigen müssen.
Ich habe diesen Ansatz basierend auf der Antwort von mjaggard gemacht:
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();
}
});
}
Hat gut für mich funktioniert.
Ich bin auf das gleiche Problem gestoßen:
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.