Co oznacza następujący wyjątek; jak mogę to naprawić?
To jest kod:
Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
To jest wyjątek:
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
Michał
źródło
źródło
compile 'com.shamanland:xdroid-toaster:0.0.5'
, nie wymagarunOnUiThread()
aniContext
zmiennej, cała rutyna zniknęła! wystarczy przywołaćToaster.toast(R.string.my_msg);
tutaj jest przykład: github.com/shamanland/xdroid-toaster-exampleOdpowiedzi:
Dzwonisz z wątku roboczego. Musisz wywoływać
Toast.makeText()
(i większość innych funkcji związanych z interfejsem użytkownika) z głównego wątku. Możesz na przykład użyć modułu obsługi.Wyszukaj temat Komunikacja z wątkiem interfejsu użytkownika w dokumentacji. W skrócie:
Inne opcje:
Możesz użyć AsyncTask , który działa dobrze dla większości rzeczy działających w tle. Ma zaczepy, które można zadzwonić, aby wskazać postęp i kiedy to się skończy.
Możesz także użyć Activity.runOnUiThread () .
źródło
(and most other functions dealing with the UI)
Przykładem funkcji interfejsu użytkownika używanej z tła jestandroid.support.design.widget.Snackbar
- jej funkcjonalność nie jest zmniejszona, gdy nie jest wywoływana z wątku interfejsu użytkownika.Musisz zadzwonić
Toast.makeText(...)
z wątku interfejsu użytkownika:Jest to wklejone z innej (duplikatu) odpowiedzi SO .
źródło
AKTUALIZACJA - 2016
Najlepszą alternatywą jest użycie
RxAndroid
(specyficzne dla wiązaniaRxJava
) dlaP
wMVP
celu przejęcie fo danych.Zacznij od powrotu
Observable
z istniejącej metody.Użyj tego obserwowalnego w ten sposób -
-------------------------------------------------- -------------------------------------------------- ------------------------------
Wiem, że jestem trochę spóźniony, ale proszę bardzo. Android zasadniczo działa na dwóch typach wątków, a mianowicie wątku interfejsu użytkownika i wątku tła . Według dokumentacji Androida -
Teraz istnieją różne metody rozwiązania tego problemu.
Wyjaśnię to przez przykład kodu:
runOnUiThread
LOOPER
AsyncTask
Treser
źródło
runOnUiThread
View
ma też metodypost(Runnable)
ipostDelayed(Runnable, long)
! Tyle handlerów na próżno. :)Toast.makeText()
powinien być wywoływany tylko z wątku Main / UI. Looper.getMainLooper () pomaga Ci to osiągnąć:Zaletą tej metody jest to, że można jej używać bez działania lub kontekstu.
źródło
Spróbuj tego, gdy zobaczysz wyjątek runtimeException ze względu na to, że Looper nie został przygotowany przed obsługą
źródło
android.os.Handler
Natknąłem się na ten sam problem i oto jak go naprawiłem:
Aby utworzyć UIHandler, musisz wykonać następujące czynności:
Mam nadzieję że to pomoże.
źródło
onCreate method
AsyncTask lub z AsyncTask. W mojej sytuacji możesz napisać cały kod, aby dowiedzieć się, jak to działa?uiHandler = new UIHandler(uiThread.getLooper());
?Przyczyna błędu:
Wątki robocze są przeznaczone do wykonywania zadań w tle i nie można wyświetlić niczego w interfejsie użytkownika w wątku roboczym, chyba że wywołasz metodę taką jak runOnUiThread . Jeśli spróbujesz wyświetlić cokolwiek w wątku interfejsu użytkownika bez wywoływania polecenia runOnUiThread, pojawi się znak
java.lang.RuntimeException
.Jeśli więc
activity
dzwoniszToast.makeText()
z wątku roboczego, wykonaj następujące czynności:Powyższy kod gwarantuje, że wyświetlasz komunikat Toast,
UI thread
ponieważ wywołujesz go wrunOnUiThread
metodzie. Więc nie więcejjava.lang.RuntimeException
.źródło
To jest to co zrobiłem.
Komponenty wizualne są „zablokowane” na zmiany z zewnętrznych wątków. Ponieważ toast pokazuje rzeczy na ekranie głównym zarządzanym przez główny wątek, musisz uruchomić ten kod w tym wątku. Mam nadzieję, że to pomoże :)
źródło
Otrzymywałem ten błąd, dopóki nie wykonałem następujących czynności.
I uczyniło to z klasy singleton:
źródło
Toaster.INSTANCE.postMessage(ResourceUtils.getString(R.string.blah));
(długo wiem! zmniejszyliśmy to później), chociaż od jakiegoś czasu nie korzystałem z tostówApplicationHolder.INSTANCE
ocenia?CustomApplication
Ustawiona zmienna statycznaCustomApplication.onCreate()
, biorąc pod uwagę, że aplikacja zawsze istnieje, dopóki proces istnieje, kontekst ten może być używany globalnieźródło
runOnUiThread(() -> { Toast toast = Toast.makeText(getApplicationContext(), "Message", Toast.LENGTH_SHORT); toast.show(); });
Cudowne rozwiązanie Kotlin:
źródło
runOnUiThread
jest częścią Activity tj.activity?.runOnUiThread { ... }
Wynika to z faktu, że Toast.makeText () dzwoni z wątku roboczego. Powinien być wywołany z głównego wątku interfejsu użytkownika w ten sposób
źródło
Odpowiedź ChicoBirda zadziałała dla mnie. Jedyną zmianą, którą wprowadziłem, było stworzenie UIHandler, gdzie musiałem to zrobić
Eclipse odmówił przyjęcia czegokolwiek innego. Wydaje mi się, że ma to sens.
Jest też
uiHandler
wyraźnie zdefiniowana gdzieś globalna klasa. Nadal nie twierdzę, że rozumiem, jak Android to robi i co się dzieje, ale cieszę się, że to działa. Teraz przejdę do studiowania i zobaczę, czy mogę zrozumieć, co robi Android i dlaczego trzeba przejść przez wszystkie te pętle. Dzięki za pomoc ChicoBird.źródło
pierwsze połączenie,
Looper.prepare()
a następnie połączenieToast.makeText().show()
ostatnieLooper.loop()
jak:źródło
Dla użytkowników Rxjava i RxAndroid:
źródło
Wystąpił ten sam problem, gdy moje oddzwaniania próbowały wyświetlić okno dialogowe.
Rozwiązałem go za pomocą dedykowanych metod w działaniu - na poziomie elementu instancji działania - które go wykorzystują
runOnUiThread(..)
źródło
Teraz handler2 użyje innego wątku do obsługi wiadomości niż główny wątek.
źródło
Aby wyświetlić okno dialogowe lub toster w wątku, najbardziej zwięzłym sposobem jest użycie obiektu Activity.
Na przykład:
źródło
Tosty, AlertDialogs musi uruchomić na wątków UI, można użyć Asynctask je właściwie wykorzystać w android development.but niektórych przypadkach musimy dostosować przerw czasowych, więc używamy wątki , ale w wątkach Nie możemy używać tosty, Alertdialogs jak używamy w AsyncTask.So Musimy oddzielić Handler dla popup tych.
w powyższym przykładzie chcę uśpić mój wątek za 3 sekundy, a następnie chcę pokazać komunikat Toast, za to w twoim module obsługi wątku głównego .
Użyłem tu skrzynki rozdzielczej, ponieważ jeśli chcesz pokazać inny komunikat w ten sam sposób, możesz użyć skrzynki przełączników w klasie Handler ... mam nadzieję, że to ci pomoże
źródło
Zwykle dzieje się tak, gdy coś w głównym wątku jest wywoływane z dowolnego wątku tła. Spójrzmy na przykład na przykład.
W powyższym przykładzie ustawiamy tekst w widoku tekstu, który znajduje się w głównym wątku interfejsu użytkownika z metody doInBackground (), która działa tylko na wątku roboczym.
źródło
Miałem ten sam problem i naprawiłem go po prostu poprzez włączenie Toast w funkcji zastępowania onPostExecute () Asynctask <> i zadziałało.
źródło
używam następującego kodu, aby wyświetlić wiadomość z kontekstu innego niż główny wątek,
następnie użyj następującego polecenia:
źródło