Premises: I have already read and tried all the solutions proposed in the other posts where other users had had the same exception
I have a thread that I start inside my app's onCreate
open class App : Application() {
override fun onCreate() {
Thread {
...
}.start()
}
}
at some point, always inside the thread, I have a class that wants to implement an observable variable using the '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"
// }
// }
}
}
Now I need that in the ViewModel I could be able to observe the variable that should update within the thread
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 ->
.....
}
}
}
In reading the log file I see that in the method of the thread where I try to assign the value
myVariable = "result"
of the variable 'by Delegates.observable' gives me an exception
"Only the original thread that created a view hierarchy can touch its views."
I solved by putting the delegate inside the couroutineScope (Dispatchers.Main).launch {...} and moving the viewModel code inside the activity into the runOnUiThread {..} method
into MyService
CoroutineScope(Dispatchers.Main).launch {
myVariable = "result"
}
into MyActivity
runOnUiThread(
myServiceInstance.onVariableChanged = {oldValue , newValue ->
.....
}
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.