webentwicklung-frage-antwort-db.com.de

Warum Handler verwenden, während runOnUiThread dasselbe tut?

Ich bin auf beide Handlers und runOnUiThread Konzepte gestoßen. Für mich scheint es jedoch immer noch ein Zweifel zu sein, bei welchen Fakten sie sich genau unterscheiden. 

Beide sind dazu gedacht, UI-Aktionen von einem Hintergrund-Thread aus auszuführen. Aber welche Faktoren müssen berücksichtigt werden, wenn wir zwischen den beiden Methoden wählen. 

Stellen Sie sich beispielsweise eine RunnableThread vor, die einen Webdienst im Hintergrund ausführt, und nun möchte ich die Benutzeroberfläche aktualisieren. 

Wie kann ich meine Benutzeroberfläche am besten aktualisieren? Soll ich Handler oder runOnUiThread wählen?

Ich weiß immer noch, dass ich eine AsyncTask verwenden und onPostExecute verwenden könnte. Aber ich möchte nur den Unterschied wissen. 

45
Andro Selva

Activity.runOnUiThread () ist ein Spezialfall allgemeinerer Handlers . Mit Handler können Sie innerhalb Ihres eigenen Threads eine eigene Ereignisabfrage erstellen. Verwenden von Handlers instanziiert mit Standardkonstruktornicht mean "Code wird im Allgemeinen auf dem UI-Thread" ausgeführt. Standardmäßig banden Handler an Thread, von der sie instanziiert wurden.

Um Handler zu erstellen, das garantiert an den UI (main) -Thread bindet, sollten Sie Handler-Objekt erstellen, das an Main Looper wie folgt gebunden ist:

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

Wenn Sie außerdem die Implementierung der runOnuiThread()-Methode überprüfen, verwendet Handler folgende Schritte: 

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

Wie Sie dem obigen Codeausschnitt entnehmen können, wird Runnable action sofort ausgeführt, wenn runOnUiThread() vom UI-Thread aufgerufen wird. Andernfalls wird es in die Variable Handler geschrieben, die später ausgeführt wird. 

70
HitOdessit

Handler haben viele Aufgaben wie Message Passing und häufige Aktualisierung der Benutzeroberfläche, wenn Sie einen Thread für einen beliebigen Task starten. Mit einem Handler können Sie Message- und Runnable-Objekte senden und verarbeiten, die der MessageQueue eines Threads zugeordnet sind, was sehr nützlich ist Viele Anwendungen wie Bluetooth-Chat, WLAN-Chat ... und Handler hat als Methode PostDelay und PostAtTime, mit denen Sie um jede Ansicht herum spielen können, um die Sichtbarkeit zu animieren und zu verändern und so weiter 

Du musst in das schauen 

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

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

1
Vipin Sahu

Nach HitOdessits Antwort.

Sie können eine Klasse so erstellen.

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

Und dann nenne es so.

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

Und dies kann von überall ausgeführt werden (wo Sie Zugriff auf Ihre Global-Klasse haben).

1
user7366285

Handler waren der alte Weg (API Level 1), Dinge zu tun, und dann wurde AsycTask (API Level 3) eingeführt, zusammen mit einem stärkeren Fokus auf der Verwendung von runOnUIThread (API Level 1). Sie sollten die Verwendung von Handlern so weit wie möglich vermeiden und je nach Bedarf die anderen beiden bevorzugen.

0
Animesh

Was wäre der beste Weg, um meine Benutzeroberfläche zu aktualisieren? Soll ich für Handler oder runOnUiThread gehen?

Wenn Ihre Runnable-Benutzeroberfläche aktualisiert werden muss, buchen Sie sie in runOnUiThread

Es ist jedoch nicht immer möglich, Runnable im UI-Thread zu posten. 

Stellen Sie sich ein Szenario vor, in dem Sie die Network/IO-Operation ausführen oder einen Webdienst aufrufen möchten. In diesem Fall können Sie keine Runnable im UI-Thread posten. Es wird Android.os.NetworkOnMainThreadException werfen

Diese Art von Runnable sollte auf anderen Threads wie HandlerThread laufen. Nach Abschluss des Vorgangs können Sie das Ergebnis mit UHandler, das dem UI-Thread zugeordnet wurde, an den UI-Thread zurückgeben.

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