Beispielkommunikation mit HandlerThread

Lesezeit: 5 Minuten

Beispielkommunikation mit HandlerThread
CL22

Ich möchte einen HandlerThread aus dem GUI-Thread einrichten. Einige Zeit später, wenn auf der GUI auf eine Schaltfläche geklickt wird, wird callHello() ausgeführt, das dann eine Nachricht an ein HelloLogger-Objekt sendet, das sich auf dem Nicht-GUI-Thread befindet, der “Hello World” asynchron protokolliert. Ich habe eine Reihe von Dingen ausprobiert, einige blockieren auf unbestimmte Zeit, andere erhalten die Nachricht nie usw. usw. Der folgende Code ist mehr oder weniger so nah wie ich, könnte ihn bitte jemand ändern, damit er funktioniert?

public class HandlerThreadExample {

    private MyHandlerThread mMyHandlerThread;
    private Looper mLooper;
    private Handler mHandler;

    public HandlerThreadExample(){
        mMyHandlerThread = new MyHandlerThread();
        mMyHandlerThread.start();
        mLooper = mMyHandlerThread.getLooper();
    }
    public void callHello() {
        mHandler.sendEmptyMessage(1);
    }
    private class MyHandlerThread extends HandlerThread {
        private HelloLogger mHelloLogger;
        private Handler mHandler;
        public MyHandlerThread() {
            super("The MyHandlerThread thread", HandlerThread.NORM_PRIORITY);
        }
        public void run (){
            mHelloLogger = new HelloLogger();
            mHandler = new Handler(getLooper()){
                public void handleMessage(Message msg){
                    mHelloLogger.logHello();
                }
            };
            super.run();
        }
    }
    private class HelloLogger {
        public HelloLogger (){
        }
        public void logHello(){
            Log.d("HandlerThreadExample", "Hello World");
        }
    }
}

Beste gefundene Beispiele:

Wenigstens kann ich jetzt die verdammten Tabs schließen

Lösung mit freundlicher Genehmigung von pskink

public class HandlerThreadExample2 {
    private static int MSG_START_HELLO = 0;
    private static int MSG_HELLO_COMPLETE = 1;
    private HandlerThread ht;
    private Handler mHtHandler;
    private Handler mUiHandler;
    private boolean helloReady = false;
    public HandlerThreadExample2(){
        ht = new HandlerThread("The new thread");
        ht.start();
        Log.d(App.TAG, "UI: handler thread started");
        mUiHandler = new Handler(){
            public void handleMessage(Message msg){
                if (msg.what == MSG_HELLO_COMPLETE){
                    Log.d(App.TAG, "UI Thread: received notification of sleep completed ");
                    helloReady = true;              }
            }
        };
        mHtHandler = new Handler(ht.getLooper()){
            public void handleMessage (Message msg){
                if (msg.what == MSG_START_HELLO){
                    Log.d(App.TAG, "handleMessage " + msg.what + " in " + Thread.currentThread() + " now sleeping");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.d(App.TAG, "Woke up, notifying UI thread...");
                    mUiHandler.sendEmptyMessage(MSG_HELLO_COMPLETE);
                }
            }
        };
    }
    public void sendLongHello(){
        if (helloReady){
            Log.d(App.TAG, "sending hello " + Thread.currentThread());      
            mHtHandler.sendEmptyMessage(MSG_START_HELLO);
            helloReady = false;
        } else {
            Log.e(App.TAG, "Cannot do hello yet - not ready");
        }
    }
}

  • Denken Sie, Sie können das in 4 Zeilen Code mit tun github.com/greenrobot/EventBus

    – cYrixmorten

    2. August 14 um 11:09 Uhr

  • Sehr interessant, danke, werde das ein anderes Mal untersuchen. +1. Aber ich denke, ich sollte gehen, bevor ich laufe

    – CL22

    2. August 14 um 11:13 Uhr

  • Kein Problem, aber um ganz ehrlich zu sein, habe ich es aufgegeben, Handler und Nachrichten zu verwenden, obwohl ich viel Android-Code geschrieben habe. Keine Notwendigkeit, es kompliziert zu machen, wenn es meiner Meinung nach sehr einfach, lesbar und wartbar ist 🙂

    – cYrixmorten

    2. August 14 um 11:15 Uhr

  • Gott weiß, ich weiß, wo du herkommst!!!! Etwas sagt mir, dass dies eine Kopfgeldfrage sein wird, lol

    – CL22

    2. August 14 um 11:24 Uhr


  • 1) Erstellen Sie einen neuen HandlerThread, 2) starten Sie ihn, 3) erstellen Sie einen neuen Handler. Verwenden von ht.getLooper() als Looper-Parameter, 4) Senden einer Nachricht

    – Pskink

    2. August 14 um 11:38 Uhr

1644109446 218 Beispielkommunikation mit HandlerThread
pskink

Dies ist ein funktionierendes Beispiel:

HandlerThread ht = new HandlerThread("MySuperAwesomeHandlerThread");
ht.start();
Handler h = new Handler(ht.getLooper()) {
    public void handleMessage(Message msg) {
        Log.d(TAG, "handleMessage " + msg.what + " in " + Thread.currentThread());
    };
};
for (int i = 0; i < 5; i++) {
    Log.d(TAG, "sending " + i + " in " + Thread.currentThread());
    h.sendEmptyMessageDelayed(i, 3000 + i * 1000);
}

AKTUALISIEREN:

Erstellen Sie zwei Klassenfelder:

Handler mHtHandler;
Handler mUiHandler;

und versuch das:

HandlerThread ht = new HandlerThread("MySuperAwsomeHandlerThread");
ht.start();
Callback callback = new Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        if (msg.what == 0) {
            Log.d(TAG, "got a meaasage in " + Thread.currentThread() + ", now sleeping... ");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Log.d(TAG, "woke up, notifying ui thread...");
            mUiHandler.sendEmptyMessage(1);
        } else
        if (msg.what == 1) {
            Log.d(TAG, "got a notification in " + Thread.currentThread());
        }
        return false;
    }
};
mHtHandler = new Handler(ht.getLooper(), callback);
mUiHandler = new Handler(callback);
mHtHandler.sendEmptyMessageDelayed(0, 3000);

Kannst du natürlich loswerden Callback Schnittstelle und erstellen Sie zwei Handler mit überschrieben handleMessage Methode…

  • +1, danke. Ich habe meine Frage bearbeitet und ein Beispiel hinzugefügt, das versucht, Ihre Antwort zu integrieren. Ich weiß immer noch nicht, wie der GUI-Thread erkennen kann, wann der Worker-Thread eine Operation beendet hat (natürlich ohne zu blockieren). Was muss ich hinzufügen, damit helloComplete() aufgerufen wird? Muss ich irgendwo einen anderen Handler machen/besorgen?

    – CL22

    3. August 14 um 9:17 Uhr

  • @pskink kannst du möglicherweise erklären, wie Callback und Looper parallel laufen, hat es mit irgendeiner Form von Scheduler zu tun?

    – Chris Stryczynski

    31. Dezember 15 um 13:48 Uhr

  • @Chris Der beste Weg, das zu lernen, besteht darin, mein zweites Code-Snippet auszuführen

    – Pskink

    31. Dezember 2015 um 14:07 Uhr

  • Wie soll das funktionieren? start() ist nicht blockierend, daher kann getLooper() in der nächsten Zeile null zurückgeben.

    – Jaroslaw Mytkalyk

    29. Juni 16 um 9:41 Uhr

  • @YaroslavMytkalyk nein, kann es nicht lesen HandlerThread#getLooper Dokumentation

    – Pskink

    29. Juni 16 um 10:19 Uhr

Das Problem, das Sie sehen, liegt daran, dass Ihre äußere Klasse ein privates mHandler-Feld verwendet, ebenso wie Ihr HandlerThread. Das Feld der äußeren Klasse wird nicht initialisiert. Sie benötigen den inneren mHandler nicht. Die äußere Klasse kann einen Handler aus dem Looper erstellen, den Sie direkt nach dem Aufruf von start() abrufen.

.

790380cookie-checkBeispielkommunikation mit HandlerThread

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy