Что означает следующее исключение; как я могу это исправить?
Это код:
Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
Это исключение:
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)
compile 'com.shamanland:xdroid-toaster:0.0.5'
, она не требуетrunOnUiThread()
илиContext
переменной, вся рутина ушла! простоToaster.toast(R.string.my_msg);
приведу вот пример: github.com/shamanland/xdroid-toaster-exampleОтветы:
Вы звоните из рабочего потока. Вы должны вызывать
Toast.makeText()
(и большинство других функций, связанных с пользовательским интерфейсом) из основного потока. Вы можете использовать обработчик, например.Посмотрите на Общение с потоком пользовательского интерфейса в документации. В двух словах:
Другие опции:
Вы можете использовать AsyncTask , который хорошо работает для большинства вещей, работающих в фоновом режиме. У него есть хуки, которые вы можете вызвать, чтобы указать прогресс и когда это будет сделано.
Вы также можете использовать Activity.runOnUiThread () .
источник
(and most other functions dealing with the UI)
Пример функции пользовательского интерфейса, которую можно использовать из фона,android.support.design.widget.Snackbar
- ее функциональность не уменьшается при отсутствии вызова из потока пользовательского интерфейса.Вам нужно позвонить
Toast.makeText(...)
из потока пользовательского интерфейса:Это скопировано из другого (дублирующего) SO ответа .
источник
ОБНОВЛЕНИЕ - 2016
Лучшей альтернативой является использование
RxAndroid
(конкретных привязок дляRxJava
) дляP
в ,MVP
чтобы взять на себя ответственность Fo данных.Начните с возврата
Observable
из вашего существующего метода.Используйте это Observable, как это -
-------------------------------------------------- -------------------------------------------------- ------------------------------
Я знаю, что немного опоздал, но здесь идет. Android в основном работает с двумя типами потоков, а именно с пользовательским интерфейсом и фоновым потоком . Согласно документации Android -
В настоящее время существуют различные способы решения этой проблемы.
Я объясню это примером кода:
runOnUiThread
LOOPER
AsyncTask
укротитель
источник
runOnUiThread
View
также есть методыpost(Runnable)
иpostDelayed(Runnable, long)
! Так много хендлеров напрасно. :)Toast.makeText()
должен вызываться только из потока Main / UI. Looper.getMainLooper () поможет вам достичь этого:Преимущество этого метода в том, что вы можете использовать его без Activity или Context.
источник
Попробуйте это, когда увидите runtimeException из-за того, что Looper не подготовлен перед обработчиком.
источник
android.os.Handler
Я столкнулся с той же проблемой, и вот как я ее исправил:
Чтобы создать UIHandler, вам необходимо выполнить следующее:
Надеюсь это поможет.
источник
onCreate method
или из AsyncTask в моей ситуации. Не могли бы вы опубликовать весь код, чтобы узнать, как все это работает?uiHandler = new UIHandler(uiThread.getLooper());
?Причина ошибки:
Рабочие потоки предназначены для выполнения фоновых задач, и вы не можете ничего показать в пользовательском интерфейсе в рабочем потоке, если вы не вызовете метод, подобный runOnUiThread . Если вы попытаетесь что-то показать в потоке пользовательского интерфейса без вызова runOnUiThread, появится сообщение
java.lang.RuntimeException
.Итак, если вы находитесь в режиме
activity
вызова, но звонитеToast.makeText()
из рабочего потока, сделайте следующее:Приведенный выше код гарантирует, что вы отображаете сообщение Toast,
UI thread
поскольку вы вызываете его внутриrunOnUiThread
метода. Так больше не надоjava.lang.RuntimeException
.источник
это то, что я сделал.
Визуальные компоненты «заблокированы» для изменений извне потоков. Итак, так как тост показывает материал на главном экране, который управляется основным потоком, вам нужно запустить этот код в этом потоке. Надеюсь, это поможет:)
источник
Я получал эту ошибку, пока я не сделал следующее.
И сделал это в одном классе:
источник
Toaster.INSTANCE.postMessage(ResourceUtils.getString(R.string.blah));
(долго я знаю! мы сократили это позже), хотя я некоторое время не использовал тостыApplicationHolder.INSTANCE
оценивать?CustomApplication
set inCustomApplication.onCreate()
, учитывая, что приложение всегда существует, а процесс существует, этот контекст можно использовать глобальноисточник
runOnUiThread(() -> { Toast toast = Toast.makeText(getApplicationContext(), "Message", Toast.LENGTH_SHORT); toast.show(); });
Замечательное решение Kotlin:
источник
runOnUiThread
является частью Деятельности, то естьactivity?.runOnUiThread { ... }
Это потому, что Toast.makeText () вызывается из рабочего потока. Это должен быть вызов из основного потока пользовательского интерфейса, как это
источник
Ответ от ChicoBird работал для меня. Единственное изменение, которое я сделал, было в создании UIHandler, где я должен был сделать
Затмение отказалось принять что-либо еще. Имеет смысл, я полагаю.
Также
uiHandler
явно определен глобальный класс. Я до сих пор не утверждаю, что понимаю, как Android это делает и что происходит, но я рад, что это работает. Теперь я приступлю к его изучению и выясню, могу ли я понять, что делает Android и почему нужно пройти через все эти обручи и петли. Спасибо за помощь ChicoBird.источник
первый звонок,
Looper.prepare()
а затем позвонитьToast.makeText().show()
последний звонок,Looper.loop()
как:источник
Для пользователей Rxjava и RxAndroid:
источник
Я столкнулся с той же проблемой, когда мои обратные вызовы пытались показать диалог.
Я решил это с помощью специальных методов в Activity - на уровне члена экземпляра Activity - которые используют
runOnUiThread(..)
источник
Теперь handler2 будет использовать другой поток для обработки сообщений, отличный от основного потока.
источник
Чтобы отобразить диалог или тостер в потоке, наиболее кратким способом является использование объекта Activity.
Например:
источник
Тост, AlertDialogs должна работать на UI потоке, вы можете использовать AsyncTask использовать их должным образом в Android development.but некоторых случаях нам нужно настроить тайм - аутов, поэтому мы используем темы , но в потоках мы не можем использовать Toast, Alertdialogs как мы используем в AsyncTask.So нам нужен отдельный обработчик для всплывающих тем.
В приведенном выше примере я хочу спать мой поток в 3 секунды, и после того, как я хочу показать сообщение Toast, для этого в вашем обработчике реализации mainthread .
Я использовал здесь регистр коммутатора, потому что если вам нужно показать разные сообщения одинаково, вы можете использовать регистр коммутатора в классе Handler ... надеюсь, это поможет вам
источник
Это обычно происходит, когда что-то в основном потоке вызывается из какого-либо фонового потока. Давайте посмотрим на пример, например.
В приведенном выше примере мы устанавливаем текст в textview, который находится в основном потоке пользовательского интерфейса, из метода doInBackground (), который работает только в рабочем потоке.
источник
У меня была та же проблема, и я исправил ее, просто поместив Toast в функцию переопределения onPostExecute () в Asynctask <>, и это сработало.
источник
я использую следующий код, чтобы показать сообщение из не основного потока "контекста",
затем используйте как следующее:
источник