web-dev-qa-db-fra.com

android - appel du thread ui depuis le thread de travail

Salut, je veux mettre Toast à ma disposition quoi qu'il arrive et disponible à partir de n'importe quel fil quand je veux dans mon application. Pour ce faire, j'ai étendu la classe Activity:

import Android.app.Activity;
import Android.os.Bundle;
import Android.os.Handler;
import Android.widget.Toast;

public class MyActivity extends Activity{
    private Handler mHandler;

    @Override   
    public void onCreate(Bundle savedInstanceState) {       
        mHandler = new Handler();
        super.onCreate(savedInstanceState);
    }

    private class ToastRunnable implements Runnable {
        String mText;

        public ToastRunnable(String text) {
            mText = text;
        }

        public void run(){
           Toast.makeText(getApplicationContext(), mText, Toast.LENGTH_SHORT).show();
        }
    }

    public void doToast(String msg) {
        mHandler.post(new ToastRunnable(msg));
    }
}

pour que les classes allActivity dans mon application soient maintenant simplement

public class AppMain extends MyActivity {
   //blah
}

ce que je pensais pouvoir faire (dans un thread de travail) était le suivant:

try{
   MyActivity me = (MyActivity) Looper.getMainLooper().getThread();
   me.doToast("Hello World");
}
catch (Exception ex){
   Log.e("oh dear", ex.getMessage());
}

et tant que le Activity était un "MyActivity" cela devrait fonctionner - mais le problème est ---> la Looper.getMainLooper().getThread(); ne retourne pas le MyActivity pour moi et ça me fait pleurer - qu'est-ce que je fais mal?

: MODIFIER:

quelques informations pour expliquer "pourquoi" je suis coincé avec ce type d'implmentation.

Je dois pouvoir confirmer à l'utilisateur qu'un événement "HTTP POST" a été un succès. Maintenant. Si l'utilisateur clique sur "OK" sur le formulaire de l'interface utilisateur, il PEUT ou PEUT NE PAS avoir Internet à ce moment-là. S'il a Internet - tout va bien - il publie le formulaire via HTTP POST - tout va bien .. mais s'il y a PAS d'Internet le plus (99,999% des applications Android applications boiteuses/pathétiques/miaulantes à cela, et en gros, n'offre pas à l'utilisateur plan "b" en supposant qu'à tout moment Internet est là - quand il ne l'est PAS)

Mon application ne "deviendra pas boiteuse (comme je l'appelle)" - elle a un plan "b" à la place, elle "met en file d'attente" l'événement de publication et réessaye toutes les x minutes .. maintenant c'est un silence fil en arrière-plan .. J'ai beaucoup d'interaction utilisateur partout dans l'application, je ne sais pas où l'utilisateur "sera", mais finalement quand HTTP POST cette file d'attente/tentatives/file d'attente/retries renvoie "! Success!" Je veux Toast cela comme un message à l'utilisateur (EG: "votre formulaire a été envoyé")

18
conners

Quel est le problème avec runOnUiThread?

http://developer.Android.com/reference/Android/app/Activity.html#runOnUiThread (Java.lang.Runnable )

activity.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show();
    }
});
53
Rawkode

utilisez le code ci-dessous. créer un objet d'activité qui contient votre instance d'activité.

activity.runOnUiThread(new Runnable() {
  public void run() {
    Toast.makeText(activity.getApplicationContext(),"Toast text",Toast.LENGTH_SHORT).show();
  }
);
6
AAnkit

Cela vous permettra d'afficher le message sans avoir besoin de s'appuyer sur le contexte pour lancer le toast, uniquement pour faire référence lors de l'affichage du message lui-même.

runOnUiThread ne fonctionnait pas à partir d'un thread OpenGL View et c'était la solution. J'espère que ça aide.

private Handler handler = new Handler();
handler.post(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show();
    }
});
4
Abandoned Cart

Vous ne pouvez pas simplement convertir le résultat de getThread() en une instance de votre classe de base MyActivity. getThread() renvoie un Thread qui n'a rien à voir avec Activity.

Il n'y a pas de bonne façon - lisez: propre - de faire ce que vous voulez faire. À un moment donné, votre abstraction "thread de travail" devra avoir une référence à quelque chose qui peut créer un Toast pour vous. Sauvegarder une variable statique contenant une référence à votre sous-classe Activity simplement pour pouvoir raccourcir la création de Toast est une recette pour les fuites de mémoire et la douleur.

2
Brian Dupuis

si vous avez le contexte avec vous, vous pouvez appeler le thread ui comme celui-ci à partir d'une classe non active.

((Activity)context).runOnUiThread(new Runnable() {
    public void run() {
        // things need to work on ui thread
    }
});
1
Chathura Jayanath

Pourquoi n'envoyez-vous pas une intention qui est capturée par un BroadCastReceiver, le récepteur de diffusion peut alors créer une notification dans la barre de notification. Ce n'est pas un toast, mais c'est un moyen d'informer l'utilisateur que son message a réussi.

1
fernandohur

Si cela relève de votre propre activité, pourquoi ne pouvez-vous pas simplement appeler doToast()?

0
Karakuri