handler.postDelayed не может обновить логическую переменную - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь создать код, который ожидает, пока не появится результат (предоставленный службой) или не пройдет секунда.

Мой код может обнаружить изменение в переменной результата, но не может обнаружить изменение, внесенное в переменную «ожидания». Я обновляю переменную ожидания в runnable, выполняемом с помощью Handler.postDelayed (). Я пытался использовать @Volatile, но все равно не повезло.

var waiting = true
var r = Runnable {
    waiting=false
    Log.d("Timeout", "timeout")
}

val handler = Handler()
handler.postDelayed(r,1000)
while(returnCall==null && waiting){continue;}
// handler.removeCallbacksAndMessages(null)

Я ожидал объект от службы или пропустил процесс, подождав секунду. Код никогда не выходит за пределы оператора while. «тайм-аут» никогда не печатается в Logcat.

Если был назначен returnCall, код продолжается, и Runnable выполняется должным образом (выводит таймаут в Logcat).

EDIT: Я использую этот код внутри функции обратного вызова

var jsInterfaceCallback = object : MyJsInterface.myJsInterfaceCallback(){
    override fun onCommand (command : String, data : HashMap<String, Any>) : MutableMap<String, Any>{
        returnCall = null
        // Pass intent to service

        var waiting = true
        var r = Runnable {
            waiting=false
            Log.d("Timeout", "timeout")
        }

        val handler = Handler()
        handler.postDelayed(r,1000)
        while(returnCall==null && waiting){continue;}
        // handler.removeCallbacksAndMessages(null)
        if(returnCall != null){
            return returnCall!!
        }
        return mutableMapOf()
    }
}

1 Ответ

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

Поскольку вы используете спин-блокировку для блокировки потока, Runnable, размещенный в том же потоке, не имеет шансов на выполнение (поток всегда занят выполнением цикла while)

Вместо использования цикла while для обнаружения изменения переменной вы должны написать функцию обратного вызова для выполнения последующего действия и вызывать ее, когда таймаут или ваша служба дали результат.

fun callback(result : YourResultType?)
{
   if(result != null)
   {
       //handle the result produced by the service
   }
   else
   {
       //timeout, do what ever you want to follow up
   }
}

var r = Runnable {
    Log.d("Timeout", "timeout")
    callback(null)
}

val handler = Handler()
handler.postDelayed(r,1000)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...