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 runOnUiThread
Methode von Thread:
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
Thread
Objektreferenz auf die Activity
in den Activity
's ein onResume
. Deaktivieren Sie es in den Activity
's onPause
. Tun Sie beides unter einem synchronized
Schloss, das sowohl das Activity
als auch Thread
respektiert.
Activity
Instanz. 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, showToast
die 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 MyActivity
in 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 Activity
oder haben View
, besteht darin, einen Handler
zum 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 Service
und Application
.
Wie dies oder das , mit ein , Runnable
dass 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 Thread
an 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.
Runnable
auf dem UI-Thread ausgeführt werden. Also poste deinen Runnable
Handler aufHandlerThread
Runnable
und senden Sie es an den UI-Thread zurück und zeigen Sie eine Toast
Nachricht an.Lösung:
HandlerThread
:requestHandler
responseHandler
und überschreiben Sie die handleMessage
Methodepost
eine Runnable
Aufgabe aufrequestHandler
Runnable
Rufen Sie innerhalb der Aufgabe sendMessage
anresponseHandler
sendMessage
Ergebnisaufruf von handleMessage
in responseHandler
.Message
und 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 Looper
zum Senden von Toast
Nachrichten 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 Activity
Sie 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.