web-dev-qa-db-fra.com

Pourquoi utiliser des gestionnaires alors que runOnUiThread fait de même?

Je suis tombé sur les deux Handlers et runOnUiThread concepts. Mais pour moi, il semble toujours y avoir un doute quant aux faits sur lesquels ils diffèrent exactement. 

Ils sont tous deux destinés à effectuer des actions d'interface utilisateur à partir d'un thread en arrière-plan. Mais quels sont les facteurs à prendre en compte lorsque nous choisissons parmi les deux méthodes. 

Par exemple, considérons une RunnableThread qui effectue un service Web en arrière-plan et je souhaite maintenant mettre à jour l'interface utilisateur. 

Quel serait le meilleur moyen de mettre à jour mon interface utilisateur? Devrais-je choisir Handler ou runOnUiThread?

Je sais toujours que je pourrais utiliser un AsyncTask et utiliser onPostExecute. Mais je veux juste connaître la différence. 

45
Andro Selva

Activity.runOnUiThread () est un cas particulier de plus générique Gestionnaires . Avec Handler, vous pouvez créer votre propre requête d'événement dans votre propre thread. Utiliser Handlers instancié avec constructeur par défautnot signifie "le code sera exécuté sur le thread d'interface utilisateur" en général. Par défaut, les gestionnaires liés à Thread à partir desquels ils ont été instanciés.

Pour créer Handler dont la liaison avec le thread UI (principal) est garantie, vous devez créer un objet Handler lié à Main Looper comme ceci:

Handler mHandler = new Handler(Looper.getMainLooper());

De plus, si vous vérifiez l’implémentation de la méthode runOnuiThread(), elle utilise Handler pour faire les choses suivantes: 

  public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

Comme vous pouvez le constater à partir de l'extrait de code ci-dessus, Runnable action sera exécuté immédiatement si runOnUiThread() est appelé à partir du thread d'interface utilisateur. Sinon, il le postera dans la Handler, qui sera exécutée ultérieurement. 

70
HitOdessit

Les gestionnaires ont de nombreux travaux comme message en passant et des mises à jour fréquentes de l'interface utilisateur si vous démarrez Un thread pour toute tâche en cours d'exécution. de nombreuses applications comme le chat bluetooth, le chat wifi ... et le gestionnaire ont comme méthode PostDelay et PostAtTime, qui vous permettent de jouer avec n'importe quelle vue pour animer et modifier la visibilité, etc. 

Vous devez regarder dans cette 

http://developer.Android.com/guide/components/processes-and-threads.html

http://developer.Android.com/tools/testing/activity_testing.html

1
Vipin Sahu

Suite à la réponse de HitOdessit.

Vous pouvez créer une classe comme celle-ci.

public class Global{
    private static Handler mHandler = new Handler(Looper.getMainLooper());
    public static void runOnUiThread(Runnable action){
        mHandler.post(action);
    }
}

Et puis appelez ça comme ça.

Global.runOnUiThread(new Runnable(){
    //Your code
});

Et cela peut être exécuté de n’importe où (où vous avez accès à votre classe Global).

1
user7366285

Les gestionnaires étaient à l’origine (API niveau 1) de faire des choses, puis AsycTask (API niveau 3) ont été introduits, avec un accent plus marqué sur l’utilisation de runOnUIThread (API niveau 1). Dans la mesure du possible, évitez d’utiliser des gestionnaires et préférez les deux autres en fonction de vos besoins.

0
Animesh

Quel serait le meilleur moyen de mettre à jour mon interface utilisateur? Devrais-je choisir Handler ou runOnUiThread?

Si votre Runnable a besoin de mettre à jour l'interface utilisateur, publiez-la sur runOnUiThread

Mais il n'est pas toujours possible de publier Runnable sur le fil de l'interface utilisateur. 

Pensez au scénario dans lequel vous souhaitez exécuter Opération réseau/IO ou appeler un service Web. Dans ce cas, vous ne pouvez pas publier Runnable dans le thread UI. Il va jeter Android.os.NetworkOnMainThreadException

Ce type de Runnable doit être exécuté sur un autre thread tel que HandlerThread . Une fois votre opération terminée, vous pouvez publier le résultat dans UI Thread en utilisant Handler, associé à UI Thread.

public void onClick(View view) {

    // onClick on some UI control, perform Network or IO operation

    /* Create HandlerThread to run Network or IO operations */
    HandlerThread handlerThread = new HandlerThread("NetworkOperation");
    handlerThread.start();

    /* Create a Handler for HandlerThread to post Runnable object */
    Handler requestHandler = new Handler(handlerThread.getLooper());

   /* Create one Handler on UI Thread to process message posted by different thread */

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void 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();
        }
    };

    NetworkRunnable r1 = new NetworkRunnable("http://www.google.com/",responseHandler);
    NetworkRunnable r2 = new NetworkRunnable("http://in.rediff.com/",responseHandler);
    requestHandler.post(r1);
    requestHandler.post(r2);

}

class NetworkRunnable implements Runnable{
    String url;
    Handler uiHandler;

    public NetworkRunnable(String url,Handler uiHandler){
        this.url = url;
        this.uiHandler=uiHandler;
    }
    public void run(){
        try {
            Log.d("Runnable", "Before IO call");
            URL page = new URL(url);
            StringBuffer text = new StringBuffer();
            HttpURLConnection conn = (HttpURLConnection) page.openConnection();
            conn.connect();
            InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
            BufferedReader buff = new BufferedReader(in);
            String line;
            while ((line = buff.readLine()) != null) {
                text.append(line + "\n");
            }
            Log.d("Runnable", "After IO call:"+ text.toString());

            Message msg = new Message();

            msg.obj = text.toString();

            /* Send result back to UI Thread Handler */
            uiHandler.sendMessage(msg);


        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}
0
Ravindra babu