Que signifie l'exception suivante? comment puis-je le réparer?
Voici le code:
Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
C'est l'exception:
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
la source
la source
compile 'com.shamanland:xdroid-toaster:0.0.5'
, elle n'a pas besoinrunOnUiThread()
ouContext
variable, toute routine est partie! juste invoquerToaster.toast(R.string.my_msg);
voici l'exemple: github.com/shamanland/xdroid-toaster-exampleRéponses:
Vous l'appelez depuis un thread de travail. Vous devez appeler
Toast.makeText()
(et la plupart des autres fonctions traitant de l'interface utilisateur) à partir du thread principal. Vous pouvez utiliser un gestionnaire, par exemple.Recherchez Communiquer avec le thread d'interface utilisateur dans la documentation. En un mot:
Autres options:
Vous pouvez utiliser une AsyncTask , qui fonctionne bien pour la plupart des choses s'exécutant en arrière-plan. Il a des crochets que vous pouvez appeler pour indiquer la progression et quand c'est fait.
Vous pouvez également utiliser Activity.runOnUiThread () .
la source
(and most other functions dealing with the UI)
Un exemple de fonction d'interface utilisateur utilisable en arrière-plan estandroid.support.design.widget.Snackbar
- sa fonctionnalité n'est pas diminuée lorsqu'elle n'appelle pas à partir du thread d'interface utilisateur.Vous devez appeler à
Toast.makeText(...)
partir du thread d'interface utilisateur:Ceci est copié-collé à partir d' une autre réponse SO (en double) .
la source
MISE À JOUR - 2016
La meilleure alternative consiste à utiliser
RxAndroid
(des liaisons spécifiques pourRxJava
) pour que l'P
inMVP
se charge des données.Commencez par revenir
Observable
de votre méthode existante.Utilisez cet observable comme ceci -
-------------------------------------------------- -------------------------------------------------- ------------------------------
Je sais que je suis un peu en retard mais c'est parti. Android fonctionne essentiellement sur deux types de threads, à savoir le thread d'interface utilisateur et le thread d'arrière - plan . Selon la documentation Android -
Il existe maintenant différentes méthodes pour résoudre ce problème.
Je vais l'expliquer par exemple de code:
runOnUiThread
LOOPER
AsyncTask
Gestionnaire
la source
runOnUiThread
View
aussi avoir des méthodespost(Runnable)
etpostDelayed(Runnable, long)
! Tant de gestionnaires en vain. :)Toast.makeText()
ne doit être appelé qu'à partir du thread principal / d'interface utilisateur. Looper.getMainLooper () vous aide à y parvenir:Un avantage de cette méthode est que vous pouvez l'utiliser sans activité ni contexte.
la source
Essayez ceci, lorsque vous voyez runtimeException en raison de Looper non préparé avant le gestionnaire.
la source
android.os.Handler
J'ai rencontré le même problème, et voici comment je l'ai résolu:
Pour créer l'UIHandler, vous devez effectuer les opérations suivantes:
J'espère que cela t'aides.
la source
onCreate method
ou depuis AsyncTask dans ma situation, veuillez poster le code entier juste pour apprendre comment les choses fonctionnent?uiHandler = new UIHandler(uiThread.getLooper());
?Raison d'une erreur:
Les threads de travail sont destinés à effectuer des tâches d'arrière-plan et vous ne pouvez rien afficher sur l'interface utilisateur dans un thread de travail, sauf si vous appelez une méthode comme runOnUiThread . Si vous essayez d'afficher quoi que ce soit sur le thread d'interface utilisateur sans appeler runOnUiThread, il y aura un
java.lang.RuntimeException
.Donc, si vous êtes dans un thread de travail,
activity
mais que vous appelezToast.makeText()
, procédez comme suit:Le code ci-dessus garantit que vous affichez le message Toast dans un
UI thread
puisque vous l'appelez à l'intérieur de larunOnUiThread
méthode. Alors pas plusjava.lang.RuntimeException
.la source
C'est ce que j'ai fait.
Les composants visuels sont "verrouillés" aux modifications des threads extérieurs. Ainsi, puisque le toast affiche des éléments sur l'écran principal gérés par le thread principal, vous devez exécuter ce code sur ce thread. J'espère que cela pourra aider:)
la source
J'obtenais cette erreur jusqu'à ce que je fasse ce qui suit.
Et en a fait une classe singleton:
la source
Toaster.INSTANCE.postMessage(ResourceUtils.getString(R.string.blah));
(longue je sais! nous l'avons réduite plus tard), bien que je n'utilise pas de toasts depuis un momentApplicationHolder.INSTANCE
évalue?CustomApplication
set inCustomApplication.onCreate()
, considérant que l'application existe toujours tant que le processus existe, ce contexte peut être utilisé globalementla source
runOnUiThread(() -> { Toast toast = Toast.makeText(getApplicationContext(), "Message", Toast.LENGTH_SHORT); toast.show(); });
Magnifique solution Kotlin:
la source
runOnUiThread
fait partie de Activity ieactivity?.runOnUiThread { ... }
Cela est dû au fait que Toast.makeText () appelle à partir d'un thread de travail. Il doit être appelé à partir du thread d'interface utilisateur principal comme celui-ci
la source
La réponse de ChicoBird a fonctionné pour moi. Le seul changement que j'ai fait a été dans la création de l'UIHandler où je devais faire
Eclipse a refusé d'accepter quoi que ce soit d'autre. C'est logique, je suppose.
De plus,
uiHandler
c'est clairement une classe globale définie quelque part. Je ne prétends toujours pas comprendre comment Android fait cela et ce qui se passe, mais je suis heureux que cela fonctionne. Maintenant, je vais l'étudier et voir si je peux comprendre ce que fait Android et pourquoi il faut passer par tous ces cercles et boucles. Merci pour l'aide ChicoBird.la source
premier appel
Looper.prepare()
puis appelez leToast.makeText().show()
dernier appelLooper.loop()
comme:la source
Pour l'utilisateur Rxjava et RxAndroid:
la source
Je rencontrais le même problème lorsque mes rappels tentaient d'afficher une boîte de dialogue.
Je l'ai résolu avec des méthodes dédiées dans l'activité - au niveau du membre d'instance d' activité - qui utilisent
runOnUiThread(..)
la source
Maintenant, handler2 utilisera un Thread différent pour gérer les messages que le Thread principal.
la source
Pour afficher une boîte de dialogue ou un grille-pain dans un fil, la manière la plus concise consiste à utiliser l'objet Activity.
Par exemple:
la source
Toast, AlertDialogs doit fonctionner sur le thread d'interface utilisateur, vous pouvez utiliser Asynctask pour les utiliser correctement dans le développement Android.Mais dans certains cas, nous devons personnaliser les délais d'attente, nous utilisons donc Threads , mais dans les threads, nous ne pouvons pas utiliser Toast, Alertdialogs comme nous dans AsyncTask. Nous avons donc besoin d'un gestionnaire séparé pour les popups .
dans l'exemple ci-dessus, je veux dormir mon thread en 3 secondes et après je veux afficher un message Toast, pour cela dans votre gestionnaire d' implémentation mainthread .
J'ai utilisé le boîtier de commutateur ici, car si vous devez afficher un message différent de la même manière, vous pouvez utiliser le boîtier de commutateur dans la classe Handler ... j'espère que cela vous aidera
la source
Cela se produit généralement lorsqu'un élément du thread principal est appelé à partir de n'importe quel thread d'arrière-plan. Regardons un exemple, par exemple.
Dans l'exemple ci-dessus, nous définissons du texte sur la vue de texte qui se trouve dans le thread d'interface utilisateur principal de la méthode doInBackground (), qui fonctionne uniquement sur un thread de travail.
la source
J'ai eu le même problème et je l'ai résolu simplement en mettant le Toast dans la fonction de substitution onPostExecute () de Asynctask <> et cela a fonctionné.
la source
j'utilise le code suivant pour afficher le message du "contexte" du thread non principal,
puis utilisez comme suit:
la source