Как создать обработчик с обратными вызовами, которые выполняются в другом потоке? - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь создать Handler, который будет обрабатывать сообщения в своем собственном потоке

То, что я сейчас делаю, выполняется во время части действия onCreate этого кода:

lateinit var _handler: Handler
lateinit var hThread: HandlerThread

fun setUpHandler() {
    hThread = HandlerThread("HandlerThread")
    hThread.start()
    _handler = Handler(hThread.looper, this::callback)
}

проблема в том, что, хотя я использую петлитель другого потока, обратный вызов выполняется в потоке пользовательского интерфейса.

Я проверил это, запустив создание этого метода:

fun callback(msg: Message): Boolean {
    Log.d("Handler", "got message ${msg.what} in thread main? ${Looper.myLooper() == Looper.getMainLooper()}")
    return true
}

когда я называю это так:

_handler.dispatchMessage(Message.obtain(_handler, 1))

Я получаю:

Handler: got message 1 in thread main? true

но когда я запускаю это так:

Handler(hThread.looper).post {
    val msg = Message.obtain()
    msg.what = 2
    callback(msg)
}

Я получаю это сообщение:

Handler: got message 2 in thread main? false

В настоящее время я использую второй подход, но из любопытства, есть ли способ заставить первый подход работать?

в качестве дополнительного вопроса: достаточно ли выполнить hThread.quit() в методе действия onDestroy, чтобы завершить дополнительный поток, который я запустил, или мне нужно сделать что-то еще?

1 Ответ

0 голосов
/ 03 января 2019

Как уже упоминалось здесь функция dispatchMessage пропускает Message через callback в любом потоке, в котором вызывается функция ... так как вы вызываете ее из потока пользовательского интерфейса, где онапоявляется.

Кроме того, FYI dispatchMessage на самом деле не используется, так как он отрицает цель использования Handler и прикрепления его к Thread и т. Д., Как прекрасно продемонстрировано здесь.

quit()завершает Looper, который по существу завершает бесконечный цикл while в действии, который сохраняет HandlerThread "живым" в его методе run(), так что да, этого должно быть достаточно, чтобы убить сам Thread.Однако следует помнить, что любые Message или Runnable, которые уже выполняются в данный момент, не будут остановлены, а все остальные Messages или Runnables в MessageQueue из Looper не будут выполнены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...