501 Stimmen

Android-Grundlagen: Code im UI-Thread ausführen

Gibt es aus der Sicht der Ausführung von Code im UI-Thread einen Unterschied zwischen:

MainActivity.this.runOnUiThread(new Runnable() {
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});

oder

MainActivity.this.myView.post(new Runnable() {
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});

et

private class BackgroundTask extends AsyncTask<String, Void, Bitmap> {
    protected void onPostExecute(Bitmap result) {
        Log.d("UI thread", "I am the UI thread");
    }
}

316voto

CommonsWare Punkte 950864

Keine dieser Maßnahmen ist genau gleich, obwohl sie alle den gleichen Nettoeffekt haben werden.

Der Unterschied zwischen dem ersten und dem zweiten Fall besteht darin, dass Sie, wenn Sie auf der Hauptanwendungs-Thread bei der Ausführung des Codes, der erste ( runOnUiThread() ) wird die Runnable sofort. Die zweite ( post() ) setzt immer die Runnable am Ende der Ereigniswarteschlange, auch wenn Sie sich bereits im Hauptanwendungs-Thread befinden.

Die dritte, vorausgesetzt, Sie erstellen und führen eine Instanz von BackgroundTask wird viel Zeit damit vergeuden, einen Thread aus dem Thread-Pool zu holen, um eine Standard-No-Op auszuführen doInBackground() bevor sie schließlich das tun, was auf eine post() . Dies ist bei weitem die am wenigsten effiziente der drei Möglichkeiten. Verwenden Sie AsyncTask wenn Sie tatsächlich Arbeit in einem Hintergrund-Thread zu erledigen haben, nicht nur für die Verwendung von onPostExecute() .

285voto

pomber Punkte 21013

Ich mag die von HPP-Kommentar kann es überall ohne Parameter verwendet werden:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        Log.d("UI thread", "I am the UI thread");
    }
});

65voto

vasart Punkte 6662

Es gibt eine vierte Möglichkeit mit Handler

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
    }
});

18voto

Joe Punkte 181

Die Antwort von Pomber ist akzeptabel, aber ich bin kein großer Fan davon, immer wieder neue Objekte zu erstellen. Die besten Lösungen sind immer die, die versuchen, Speicherfresser zu entschärfen. Ja, es gibt eine automatische Garbage Collection, aber die Speichererhaltung in einem mobilen Gerät fällt in den Rahmen der Best Practice. Der folgende Code aktualisiert eine TextView in einem Dienst.

TextViewUpdater textViewUpdater = new TextViewUpdater();
Handler textViewUpdaterHandler = new Handler(Looper.getMainLooper());
private class TextViewUpdater implements Runnable{
    private String txt;
    @Override
    public void run() {
        searchResultTextView.setText(txt);
    }
    public void setText(String txt){
        this.txt = txt;
    }

}

So kann es von überall aus genutzt werden:

textViewUpdater.setText("Hello");
        textViewUpdaterHandler.post(textViewUpdater);

13voto

Dick Lucas Punkte 11769

Ab Android P können Sie Folgendes verwenden getMainExecutor() :

getMainExecutor().execute(new Runnable() {
  @Override public void run() {
    // Code will run on the main thread
  }
});

Von der [Dokumente für Android-Entwickler](https://developer.android.com/reference/android/content/Context.html#getMainExecutor()) :

Gibt einen Executor zurück, der die in der Warteschlange stehenden Aufgaben auf dem mit diesem Kontext verbundenen Haupt-Thread ausführt. Dies ist der Thread, über den Aufrufe an Anwendungskomponenten (Aktivitäten, Dienste usw.) abgewickelt werden.

Von der CommonsBlog :

Sie können getMainExecutor() auf Context aufrufen, um einen Executor zu erhalten, der seine Aufträge auf dem Hauptanwendungs-Thread ausführt. Es gibt andere Möglichkeiten, dies zu erreichen, indem man Looper und eine eigene Executor-Implementierung verwendet, aber dies ist einfacher.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X