Android Kotlin от Delegates.observable из фонового потока в ViewModel - PullRequest
0 голосов
/ 18 июня 2020

Предпосылки: я уже прочитал и попробовал все решения, предложенные в других сообщениях, где у других пользователей было такое же исключение

У меня есть ветка, которую я запускаю внутри своего приложения onCreate

open class App : Application() {

   override fun onCreate() {

      Thread {
           ...
             }.start()
   }
}

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

class MyService{

    var myVariable: String by Delegates.observable("default value") { _, oldValue, newValue ->
        onVariableChanged?.invoke(oldValue, newValue)
    }
    var onVariableChanged: ((String, String) -> Unit)? = null

    fun doSomething(){

     myVariable = "result"

     // ----      I also tried the 2 solutions commented below  ----
//
//            val handler = Handler(getMainLooper())
//            handler.post {myVariable = "result"}

//            GlobalScope.launch {
//                withContext(Dispatchers.Main){
//                   myVariable = "result"
//                }
//            }


    }

}

Теперь мне нужно это в ViewModel я мог наблюдать переменную, которая должна обновляться в потоке

class MyViewModel(application: Application) : AndroidViewModel(application) {

//     ---- I also tried with couroutines  --------
  //    private val viewModelJob = SupervisorJob()
//    private val viewModelScope = CoroutineScope(viewModelJob + Dispatchers.Main)  

 init {

//        viewModelScope.launch {
//            onVariableThreadChanged()
//        }

        onVariableThreadChanged()
      }

   private fun onVariableThreadChanged(){
           myServiceInstance.onVariableChanged = {oldValue , newValue ->
              .....
           }
   }

}

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

myVariable = "result"

переменной 'by Delegates.observable' дает мне исключение

«Только исходный поток, создавший иерархию представлений, может касаться его представлений».

1 Ответ

0 голосов
/ 22 июня 2020

Я решил, поместив делегата в CouroutineScope (Dispatchers.Main) .launch {...} и переместив код viewModel внутри действия в метод runOnUiThread {..}

в MyService

  CoroutineScope(Dispatchers.Main).launch {
                            myVariable = "result"
                        }

в MyActivity

  runOnUiThread(
            myServiceInstance.onVariableChanged = {oldValue , newValue  ->
              .....
             }
         )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...