Je ne suis pas sûr de comprendre comment faire cela. J'ai mon vide public existant run (). J'ai essayé de mettre ce code là-bas. Je sais que ce n'est pas juste parce que ça n'a pas marché, mais je suis vraiment coincé.
SwimBikeRun
14
Est-ce que "activité" est passée au thread non-ui dans son constructeur? Quelle est la bonne façon d'obtenir l'objet d'activité que vous utilisez à partir du thread séparé?
snapfractalpop
Définissez la Threadréférence de l' objet à la Activitydans les Activity« s onResume. Désactivez-le dans le Activity's onPause. Faites les deux sous une synchronizedserrure qui respecte Activityet Threadrespecte.
JohnnyLambada
5
parfois il n'y a pas d'accès à l' Activityinstance, vous pouvez utiliser une simple classe d'assistance à la place, voir ici: stackoverflow.com/a/18280318/1891118
Oleksii K.
5
J'ai généralement trouvé que cela MyActivity.this.runOnUiThread()fonctionne très bien depuis un fichier Thread/ AsyncTask.
Anthony Atkinson
62
J'aime avoir une méthode dans mon activité appelée showToastque je peux appeler de n'importe où ...
@YoushaAleayoub Il y a beaucoup de discussions et de devinettes dans les liens que vous avez fournis. Par exemple, RomainGuy dit qu'il n'y a pas de fuite de mémoire dans votre preuve non. 4. Certains des liens datent des débuts d'Android en 2009. Les gens disent également dans les autres liens que vous pouvez utiliser les deux contextes. Activité et application. Peut-être avez-vous une preuve factuelle plus à jour? Avez-vous un lien pour 1?
OneWorld
28
Ceci est similaire à d'autres réponses, mais mis à jour pour les nouveaux apis disponibles et beaucoup plus propre. Aussi, ne suppose pas que vous êtes dans un contexte d'activité.
Lorsque le contexte que vous avez n'est pas une activité, c'est la réponse parfaite. Merci beaucoup!
francas
17
Une approche qui fonctionne à peu près n'importe où, y compris à partir d'endroits où vous n'avez pas de Activityou View, consiste à attraper un Handlerdans le fil principal et à montrer le toast:
Comme ceci ou ceci , avec un Runnablequi montre le Toast. À savoir,
Activity activity =// reference to an Activity// orView view =// reference to a View
activity.runOnUiThread(newRunnable(){@Overridepublicvoid run(){
showToast(activity);}});// or
view.post(newRunnable(){@Overridepublicvoid run(){
showToast(view.getContext());}});privatevoid showToast(Context ctx){Toast.makeText(ctx,"Hi!",Toast.LENGTH_SHORT).show();}
Parfois, vous devez envoyer un message d'un autre Threadau thread d'interface utilisateur. Ce type de scénario se produit lorsque vous ne pouvez pas exécuter d'opérations réseau / E / S sur le thread d'interface utilisateur.
L'exemple ci-dessous gère ce scénario.
Vous avez un fil d'interface utilisateur
Vous devez démarrer l'opération IO et vous ne pouvez donc pas exécuter Runnablesur le thread d'interface utilisateur. Alors postez votre Runnablegestionnaire surHandlerThread
Récupérez le résultat Runnableet renvoyez-le au fil d'interface utilisateur et affichez un Toastmessage.
Créer un gestionnaire avec le Looper à partir du thread principal: responseHandleret la handleMessageméthode de substitution
postune Runnabletâche surrequestHandler
A l' intérieur Runnabletâche, appelez sendMessageleresponseHandler
Cet sendMessageappel de résultat de handleMessagein responseHandler.
Obtenez des attributs de Messageet traitez-les, mettez à jour l'interface utilisateur
Exemple de code:
/* Handler thread */HandlerThread handlerThread =newHandlerThread("HandlerThread");
handlerThread.start();Handler requestHandler =newHandler(handlerThread.getLooper());finalHandler responseHandler =newHandler(Looper.getMainLooper()){@Overridepublicvoid handleMessage(Message msg){//txtView.setText((String) msg.obj);Toast.makeText(MainActivity.this,"Runnable on HandlerThread is completed and got result:"+(String)msg.obj,Toast.LENGTH_LONG).show();}};for(int i=0; i<5; i++){Runnable myRunnable =newRunnable(){@Overridepublicvoid run(){try{/* Add your business logic here and construct the
Messgae which should be handled in UI thread. For
example sake, just sending a simple Text here*/String text =""+(++rId);Message msg =newMessage();
msg.obj = text.toString();
responseHandler.sendMessage(msg);System.out.println(text.toString());}catch(Exception err){
err.printStackTrace();}}};
requestHandler.post(myRunnable);}
E/AndroidRuntime: FATAL EXCEPTION:Thread-4Process: com.example.languoguang.welcomeapp, PID:4724
java.lang.RuntimeException:Can't toast on a thread that has not called Looper.prepare()
at android.widget.Toast$TN.<init>(Toast.java:393)
at android.widget.Toast.<init>(Toast.java:117)
at android.widget.Toast.makeText(Toast.java:280)
at android.widget.Toast.makeText(Toast.java:270)
at com.example.languoguang.welcomeapp.MainActivity$1.run(MainActivity.java:51)
at java.lang.Thread.run(Thread.java:764)
I/Process: Sending signal. PID: 4724 SIG: 9
Application terminated.
Réponses:
Vous pouvez le faire en appelant une
Activity
de »runOnUiThread
méthode de votre fil:la source
Thread
référence de l' objet à laActivity
dans lesActivity
« sonResume
. Désactivez-le dans leActivity
'sonPause
. Faites les deux sous unesynchronized
serrure qui respecteActivity
etThread
respecte.Activity
instance, vous pouvez utiliser une simple classe d'assistance à la place, voir ici: stackoverflow.com/a/18280318/1891118MyActivity.this.runOnUiThread()
fonctionne très bien depuis un fichierThread
/AsyncTask
.J'aime avoir une méthode dans mon activité appelée
showToast
que je peux appeler de n'importe où ...Je l'appelle alors le plus souvent de l'intérieur
MyActivity
sur n'importe quel fil comme celui-ci ...la source
Ceci est similaire à d'autres réponses, mais mis à jour pour les nouveaux apis disponibles et beaucoup plus propre. Aussi, ne suppose pas que vous êtes dans un contexte d'activité.
la source
Une approche qui fonctionne à peu près n'importe où, y compris à partir d'endroits où vous n'avez pas de
Activity
ouView
, consiste à attraper unHandler
dans le fil principal et à montrer le toast:L'avantage de cette approche est qu'elle fonctionne avec tout
Context
, y comprisService
etApplication
.la source
Comme ceci ou ceci , avec un
Runnable
qui montre leToast
. À savoir,la source
Parfois, vous devez envoyer un message d'un autre
Thread
au thread d'interface utilisateur. Ce type de scénario se produit lorsque vous ne pouvez pas exécuter d'opérations réseau / E / S sur le thread d'interface utilisateur.L'exemple ci-dessous gère ce scénario.
Runnable
sur le thread d'interface utilisateur. Alors postez votreRunnable
gestionnaire surHandlerThread
Runnable
et renvoyez-le au fil d'interface utilisateur et affichez unToast
message.Solution:
HandlerThread
:requestHandler
responseHandler
et lahandleMessage
méthode de substitutionpost
uneRunnable
tâche surrequestHandler
Runnable
tâche, appelezsendMessage
leresponseHandler
sendMessage
appel de résultat dehandleMessage
inresponseHandler
.Message
et traitez-les, mettez à jour l'interface utilisateurExemple de code:
Articles utiles:
handlerthreads-et-pourquoi-vous-devriez-les-utiliser-dans-vos-applications-android
android-looper-handler-handlerthread-i
la source
handler.sendMessage();
post()
Méthode d' appelhandler.post();
runOnUiThread()
view.post()
la source
Vous pouvez utiliser
Looper
pour envoyer unToast
message. Passez par ce lien pour plus de détails.et il est appelé dans votre fil. Contexte peut être
Activity.getContext()
obtient duActivity
vous devez montrer le pain grillé.la source
J'ai fait cette approche basée sur la réponse de mjaggard:
A bien fonctionné pour moi.
la source
J'ai rencontré le même problème:
Avant: fonction onCreate
Après: fonction onCreate
ça a marché.
la source