O que significa a seguinte exceção; como posso consertar isso?
Este é o código:
Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
Esta é a exceção:
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
fonte
fonte
compile 'com.shamanland:xdroid-toaster:0.0.5'
, não requerrunOnUiThread()
ouContext
variável, toda a rotina se foi! apenas invocarToaster.toast(R.string.my_msg);
aqui está o exemplo: github.com/shamanland/xdroid-toaster-exampleRespostas:
Você está chamando isso de um thread de trabalho. Você precisa chamar
Toast.makeText()
(e a maioria das outras funções que lidam com a interface do usuário) de dentro do thread principal. Você pode usar um manipulador, por exemplo.Consulte Comunicação com o thread da interface do usuário na documentação. Em poucas palavras:
Outras opções:
Você pode usar um AsyncTask , que funciona bem para a maioria das coisas em execução em segundo plano. Tem ganchos que você pode chamar para indicar o progresso e quando terminar.
Você também pode usar Activity.runOnUiThread () .
fonte
(and most other functions dealing with the UI)
Um exemplo de uma função de interface do usuário utilizável em segundo plano éandroid.support.design.widget.Snackbar
- sua funcionalidade é diminuída quando não é chamada a partir do thread da interface do usuário.Você precisa chamar
Toast.makeText(...)
do thread da interface do usuário:Isso é copiado e colado de outra resposta do SO (duplicada) .
fonte
ATUALIZAÇÃO - 2016
A melhor alternativa é usar
RxAndroid
(ligações específicas paraRxJava
) para oP
noMVP
para assumir o comando fo dados.Comece retornando
Observable
do seu método existente.Use este Observável assim -
-------------------------------------------------- -------------------------------------------------- ------------------------------
Eu sei que estou um pouco atrasado, mas aqui vai. O Android basicamente funciona em dois tipos de encadeamentos, ou seja, encadeamento da interface do usuário e encadeamento em segundo plano . De acordo com a documentação do Android -
Agora, existem vários métodos para resolver esse problema.
Vou explicar isso por exemplo de código:
runOnUiThread
LOOPER
AsyncTask
Handler
fonte
runOnUiThread
View
também tem métodospost(Runnable)
epostDelayed(Runnable, long)
! Tantos manipuladores em vão. :)Toast.makeText()
deve ser chamado apenas do thread Principal / UI. Looper.getMainLooper () ajuda você a alcançá-lo:Uma vantagem desse método é que você pode usá-lo sem Atividade ou Contexto.
fonte
Tente isso quando vir runtimeException devido ao Looper não preparado antes do manipulador.
fonte
android.os.Handler
Corri para o mesmo problema, e aqui está como corrigi-lo:
Para criar o UIHandler, você precisará executar o seguinte:
Espero que isto ajude.
fonte
onCreate method
ou do AsyncTask na minha situação. Você pode publicar o código inteiro apenas para saber como as coisas funcionam?uiHandler = new UIHandler(uiThread.getLooper());
?Razão para um erro:
Os encadeamentos de trabalho destinam-se à execução de tarefas em segundo plano e você não pode mostrar nada na interface do usuário em um encadeamento de trabalho, a menos que chame um método como runOnUiThread . Se você tentar mostrar algo no thread da interface do usuário sem chamar runOnUiThread, haverá um
java.lang.RuntimeException
.Portanto, se você estiver em uma
activity
chamada, masToast.makeText()
do segmento de trabalho, faça o seguinte:O código acima garante que você esteja mostrando a mensagem Toast em um método
UI thread
desde que a está chamando dentrorunOnUiThread
. Então não maisjava.lang.RuntimeException
.fonte
Isso é o que eu fiz.
Os componentes visuais estão "bloqueados" para alterações de threads externos. Portanto, como o brinde mostra coisas na tela principal que são gerenciadas pelo thread principal, você precisa executar esse código nesse segmento. Espero que ajude:)
fonte
Eu estava recebendo esse erro até fazer o seguinte.
E transformou isso em uma classe singleton:
fonte
Toaster.INSTANCE.postMessage(ResourceUtils.getString(R.string.blah));
(longa Sei que reduziu esta tarde!), embora eu não tenha vindo a utilizar brindes em quandoApplicationHolder.INSTANCE
avaliar para?CustomApplication
conjunto emCustomApplication.onCreate()
, considerando-se a aplicação sempre existe, enquanto existe o processo, neste contexto, pode ser utilizada a nível mundialfonte
runOnUiThread(() -> { Toast toast = Toast.makeText(getApplicationContext(), "Message", Toast.LENGTH_SHORT); toast.show(); });
Maravilhosa solução Kotlin:
fonte
runOnUiThread
faz parte da atividade, ou seja,activity?.runOnUiThread { ... }
Isso ocorre porque Toast.makeText () está chamando de um thread de trabalho. Deve ser chamada do thread principal da interface do usuário como este
fonte
A resposta de ChicoBird funcionou para mim. A única alteração que fiz foi na criação do UIHandler, onde eu tive que fazer
Eclipse se recusou a aceitar qualquer outra coisa. Faz sentido, suponho.
Também
uiHandler
é claramente uma classe global definida em algum lugar. Ainda não pretendo entender como o Android está fazendo isso e o que está acontecendo, mas estou feliz que funcione. Agora vou estudá-lo e ver se consigo entender o que o Android está fazendo e por que é preciso passar por todos esses ciclos. Obrigado pela ajuda ChicoBird.fonte
primeira
Looper.prepare()
e depois aToast.makeText().show()
última,Looper.loop()
como:fonte
Para usuários Rxjava e RxAndroid:
fonte
Eu estava com o mesmo problema quando meus retornos de chamada tentavam mostrar uma caixa de diálogo.
Eu o resolvi com métodos dedicados na Activity - no nível de membro da instância Activity - que usam
runOnUiThread(..)
fonte
Agora handler2 usará um Thread diferente para manipular as mensagens que o Thread principal.
fonte
Para exibir uma caixa de diálogo ou uma torradeira em um thread, a maneira mais concisa é usar o objeto Activity.
Por exemplo:
fonte
Brinde, AlertDialogs precisa ser executado no segmento interface do usuário, você pode usar AsyncTask usá-los corretamente no android development.but alguns casos precisamos personalizar os pedidos de tempo, por isso usamos Threads , mas em tópicos que não podemos usar brinde, Alertdialogs como nós usando no AsyncTask.So, precisamos de Handler separado para pop-up.
no exemplo acima, quero dormir meu segmento em 3seg e depois quero mostrar uma mensagem do Toast, para isso no seu manipulador de implementos mainthread .
Usei switch case aqui, porque se você precisar mostrar uma mensagem diferente da mesma maneira, poderá usar switch case na classe Handler ... espero que isso ajude você
fonte
Isso geralmente acontece quando algo no thread principal é chamado de qualquer thread em segundo plano. Vamos ver um exemplo, por exemplo.
No exemplo acima, estamos definindo texto no textview que está no thread principal da interface do usuário do método doInBackground (), que opera apenas em um thread de trabalho.
fonte
Eu tive o mesmo problema e o corrigi simplesmente colocando a Toast na função de substituição onPostExecute () do Asynctask <> e funcionou.
fonte
eu uso o código a seguir para mostrar a mensagem do segmento não principal "contexto",
em seguida, use o seguinte:
fonte