401 Stimmen

Ausführen von Code im Hauptthread von einem anderen Thread aus

In einem Android-Dienst habe ich Thread(s) erstellt, um einige Hintergrundaufgaben zu erledigen.

Ich habe eine Situation, in der ein Thread eine bestimmte Aufgabe in die Nachrichtenwarteschlange des Hauptthreads stellen muss, zum Beispiel eine Runnable .

Gibt es eine Möglichkeit, die Handler des Hauptthemas und posten Message / Runnable aus meinem anderen Thread?

30voto

Alexander Volkov Punkte 7318

Wenn Sie Code in einem Thread ausführen, z.B. um eine Aktion zu verzögern, dann müssen Sie die runOnUiThread aus dem Kontext. Zum Beispiel, wenn Ihr Code innerhalb von MainActivity Klasse, dann verwenden Sie dies:

MainActivity.this.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        myAction();
    }
});

Wenn Ihre Methode entweder von main (UI-Thread) oder von anderen Threads aufgerufen werden kann, benötigen Sie eine Prüfung wie:

public void myMethod() {
   if( Looper.myLooper() == Looper.getMainLooper() ) {
       myAction();
   }
   else {

}

9voto

mevdev Punkte 701

Ich weiß, dies ist eine alte Frage, aber ich stieß auf einen Haupt-Thread-Einzeiler, den ich sowohl in Kotlin als auch in Java verwende. Dies ist vielleicht nicht die beste Lösung für einen Dienst, aber für den Aufruf von etwas, das die Benutzeroberfläche innerhalb eines Fragments ändert, ist dies extrem einfach und offensichtlich.

Java (8):

 getActivity().runOnUiThread(()->{
      //your main thread code
 });

Kotlin:

this.runOnUiThread {
     //your main thread code
}

7voto

Inn0vative1 Punkte 1794

Der einfachste Weg, vor allem, wenn Sie nicht über einen Kontext, wenn Sie mit RxAndroid Sie tun können:

AndroidSchedulers.mainThread().scheduleDirect {
    runCodeHere()
}

7voto

Ravindra babu Punkte 45577

HandlerThread ist eine bessere Option als normale Java-Threads in Android.

  1. Erstellen einer HandlerThread und starten Sie es
  2. Erstellen einer Handler con Looper von HandlerThread : requestHandler
  3. post a Runnable Aufgabe an requestHandler

Kommunikation mit UI Thread von HandlerThread

  1. Erstellen einer Handler con Looper für den Hauptfaden : responseHandler und außer Kraft setzen handleMessage Methode
  2. Innerhalb Runnable Aufgabe eines anderen Threads ( HandlerThread in diesem Fall), rufen Sie sendMessage sur responseHandler
  3. Diese sendMessage Ergebnis Aufruf von handleMessage en responseHandler .
  4. Holen Sie sich Attribute aus der Message und verarbeiten, UI aktualisieren

Ejemplo : Aktualisierung TextView mit den von einem Webdienst empfangenen Daten. Da der Webdienst auf einem Nicht-UI-Thread aufgerufen werden sollte, wurde HandlerThread für den Netzbetrieb. Sobald Sie den Inhalt vom Webdienst erhalten haben, senden Sie eine Nachricht an Ihren Haupt-Thread (UI-Thread) und die Handler behandelt die Nachricht und aktualisiert die Benutzeroberfläche.

Beispiel-Code:

HandlerThread handlerThread = new HandlerThread("NetworkOperation");
handlerThread.start();
Handler requestHandler = new Handler(handlerThread.getLooper());

final Handler responseHandler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {
        txtView.setText((String) msg.obj);
    }
};

Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        try {
            Log.d("Runnable", "Before IO call");
            URL page = new URL("http://www.your_web_site.com/fetchData.jsp");
            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();
            responseHandler.sendMessage(msg);

        } catch (Exception err) {
            err.printStackTrace();
        }
    }
};
requestHandler.post(myRunnable);

Nützliche Artikel:

handlerthreads-und-warum-man-sie-in-ihren-Android-Apps-verwenden-sollte

Android-looper-handler-handlerthread-i

6voto

Hamed Jaliliani Punkte 2613

Präziserer Kotlin-Code mit Handler :

Handler(Looper.getMainLooper()).post {  
 // your codes here run on main Thread
 }

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