Was bedeutet die folgende Ausnahme? wie kann ich es reparieren?
Dies ist der Code:
Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
Dies ist die Ausnahme:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)
at android.widget.Toast.<init>(Toast.java:68)
at android.widget.Toast.makeText(Toast.java:231)
android
ui-thread
android-toast
Michael
quelle
quelle
compile 'com.shamanland:xdroid-toaster:0.0.5'
, es ist nicht erforderlichrunOnUiThread()
oderContext
variabel, alle Routine ist weg!Toaster.toast(R.string.my_msg);
Antworten:
Sie rufen es von einem Arbeitsthread aus auf. Sie müssen
Toast.makeText()
(und die meisten anderen Funktionen, die sich mit der Benutzeroberfläche befassen) aus dem Hauptthread heraus aufrufen . Sie könnten beispielsweise einen Handler verwenden.Nachschlagen Kommunikation mit dem UI - Thread in der Dokumentation. In einer Nussschale:
Andere Optionen:
Sie können eine AsyncTask verwenden , die für die meisten Dinge, die im Hintergrund ausgeführt werden, gut funktioniert. Es hat Hooks, die Sie aufrufen können, um den Fortschritt anzuzeigen und wann es fertig ist.
Sie können auch Activity.runOnUiThread () verwenden .
quelle
(and most other functions dealing with the UI)
Ein Beispiel für eine UI-Funktion, die im Hintergrund verwendet werden kann, istandroid.support.design.widget.Snackbar
- ihre Funktionalität ist unvermindert, wenn nicht vom UI-Thread aus aufgerufen wird.Sie müssen
Toast.makeText(...)
vom UI-Thread aus aufrufen :Dies wird aus einer anderen (doppelten) SO-Antwort kopiert .
quelle
UPDATE - 2016
Die beste Alternative ist die Verwendung
RxAndroid
(spezifische Bindungen fürRxJava
) für denP
inMVP
fo Daten zu übernehmen.Kehren Sie zunächst von
Observable
Ihrer vorhandenen Methode zurück.Verwenden Sie dieses Observable wie folgt -
-------------------------------------------------- -------------------------------------------------- ------------------------------
Ich weiß, ich bin etwas spät dran, aber jetzt geht es los. Android funktioniert grundsätzlich mit zwei Thread-Typen, nämlich UI-Thread und Hintergrund-Thread . Laut Android-Dokumentation -
Nun gibt es verschiedene Methoden, um dieses Problem zu lösen.
Ich werde es anhand eines Codebeispiels erklären:
runOnUiThread
LOOPER
AsyncTask
Handler
quelle
runOnUiThread
View
auch Methoden gibtpost(Runnable)
undpostDelayed(Runnable, long)
! So viele Handler vergebens. :)Toast.makeText()
sollte nur vom Haupt- / UI-Thread aufgerufen werden. Looper.getMainLooper () hilft Ihnen dabei:Ein Vorteil dieser Methode ist, dass Sie sie ohne Aktivität oder Kontext verwenden können.
quelle
Versuchen Sie dies, wenn Sie runtimeException sehen, weil Looper vor dem Handler nicht vorbereitet wurde.
quelle
android.os.Handler
Ich bin auf dasselbe Problem gestoßen, und hier ist, wie ich es behoben habe:
Um den UIHandler zu erstellen, müssen Sie Folgendes ausführen:
Hoffe das hilft.
quelle
onCreate method
bin mir nicht sicher, wie ich in meiner Situation von oder von AsyncTask anrufen soll. Bitte posten Sie den gesamten Code, um zu erfahren, wie die Dinge funktionieren.uiHandler = new UIHandler(uiThread.getLooper());
?Grund für einen Fehler:
Worker-Threads sind für Hintergrundaufgaben gedacht und Sie können innerhalb eines Worker-Threads nichts auf der Benutzeroberfläche anzeigen, es sei denn, Sie rufen eine Methode wie runOnUiThread auf . Wenn Sie versuchen, etwas im UI-Thread anzuzeigen, ohne runOnUiThread aufzurufen, wird ein angezeigt
java.lang.RuntimeException
.Also, wenn Sie in einem sind
activity
aber AufrufToast.makeText()
von Worker - Thread, dies zu tun:Der obige Code stellt sicher, dass Sie die Toast-Nachricht in einer anzeigen,
UI thread
da Sie sie innerhalb derrunOnUiThread
Methode aufrufen . Also nicht mehrjava.lang.RuntimeException
.quelle
das ist, was ich tat.
Visuelle Komponenten sind für Änderungen von externen Threads "gesperrt". Da der Toast also Dinge auf dem Hauptbildschirm anzeigt, die vom Hauptthread verwaltet werden, müssen Sie diesen Code auf diesem Thread ausführen. Ich hoffe, das hilft:)
quelle
Ich habe diesen Fehler erhalten, bis ich Folgendes getan habe.
Und machte dies zu einer Singleton-Klasse:
quelle
Toaster.INSTANCE.postMessage(ResourceUtils.getString(R.string.blah));
(lange weiß ich! Wir haben sie später reduziert), obwohl ich seit einiger Zeit keinen Toast mehr verwendet habeApplicationHolder.INSTANCE
bewertet also?CustomApplication
set inCustomApplication.onCreate()
, da die Anwendung immer vorhanden ist, während der Prozess vorhanden ist, kann dieser Kontext global verwendet werdenquelle
runOnUiThread(() -> { Toast toast = Toast.makeText(getApplicationContext(), "Message", Toast.LENGTH_SHORT); toast.show(); });
Wunderbare Kotlin-Lösung:
quelle
runOnUiThread
ist ein Teil der Aktivität dhactivity?.runOnUiThread { ... }
Dies liegt daran, dass Toast.makeText () von einem Arbeitsthread aus aufruft. Es sollte wie folgt vom Haupt-UI-Thread aufgerufen werden
quelle
Die Antwort von ChicoBird hat bei mir funktioniert. Die einzige Änderung, die ich vorgenommen habe, war die Erstellung des UIHandlers, in dem ich etwas tun musste
Eclipse weigerte sich, etwas anderes zu akzeptieren. Das macht wohl Sinn.
Auch das
uiHandler
ist eindeutig eine Klasse global irgendwo definiert. Ich behaupte immer noch nicht zu verstehen, wie Android das macht und was los ist, aber ich bin froh, dass es funktioniert. Jetzt werde ich es studieren und sehen, ob ich verstehen kann, was Android tut und warum man all diese Reifen und Schleifen durchlaufen muss. Danke für die Hilfe ChicoBird.quelle
erster Anruf
Looper.prepare()
und dannToast.makeText().show()
letzter AnrufLooper.loop()
wie folgt :quelle
Für Rxjava- und RxAndroid-Benutzer:
quelle
Ich hatte das gleiche Problem, als meine Rückrufe versuchten, einen Dialog anzuzeigen.
Ich habe es mit dedizierten Methoden in der Aktivität - auf der Ebene der Mitglieder der Aktivitätsinstanz - gelöst, die diese verwenden
runOnUiThread(..)
quelle
Jetzt verwendet handler2 einen anderen Thread, um die Nachrichten zu verarbeiten als der Haupt-Thread.
quelle
Um einen Dialog oder einen Toaster in einem Thread anzuzeigen, verwenden Sie am einfachsten das Activity-Objekt.
Zum Beispiel:
quelle
Toast, AlertDialogs muss auf einem UI-Thread ausgeführt werden. Sie können Asynctask verwenden , um sie in der Android-Entwicklung ordnungsgemäß zu verwenden. In einigen Fällen müssen wir jedoch die Zeitüberschreitungen anpassen, sodass wir Threads verwenden , aber in Threads können wir Toast nicht verwenden, Alertdialogs wie wir In AsyncTask.So benötigen wir einen separaten Handler für Popup- Dateien .
Im obigen Beispiel möchte ich meinen Thread in 3 Sekunden schlafen lassen und nachdem ich eine Toast-Nachricht anzeigen möchte, dafür in Ihrem Mainthread- Implementierungshandler.
Ich habe hier Switch Case verwendet, da Sie, wenn Sie unterschiedliche Nachrichten auf dieselbe Weise anzeigen müssen, Switch Case innerhalb der Handler-Klasse verwenden können. Ich hoffe, dies hilft Ihnen dabei
quelle
Dies geschieht normalerweise, wenn etwas im Haupt-Thread von einem Hintergrund-Thread aufgerufen wird. Schauen wir uns zum Beispiel ein Beispiel an.
Im obigen Beispiel legen wir Text in der Textansicht fest, die sich im Haupt-UI-Thread der Methode doInBackground () befindet, die nur für einen Arbeitsthread ausgeführt wird.
quelle
Ich hatte das gleiche Problem und habe es einfach behoben, indem ich den Toast in die onPostExecute () - Überschreibungsfunktion der Asynctask <> eingefügt habe, und es hat funktioniert.
quelle
Ich benutze den folgenden Code, um Nachricht von Nicht-Haupt-Thread "Kontext" anzuzeigen,
Verwenden Sie dann wie folgt:
quelle