如何从协程结果访问视图属性
How to acces view properties from coroutines result
我正在尝试使用协程向后端发出简单请求
uiScope.launch {
try {
result = URL("https://httpbin.org/get").readText()
text.text = result
} catch (error: Error) {
text.text = error.message
} finally {
log(this@MainActivity,result)
}
}
但是抛出了这个异常:
android.view.ViewRootImpl$CalledFromWrongThreadException
: Only the original thread that created a view hierarchy can touch its views.
如何解决?
您的 uiScope
设置不正确,显然它的调度程序不是 Dispatchers.Main
。所以首先要修复的是 coroutineContext
属性 的实现,它应该是
override val coroutineContext = Dispatchers.Main + SupervisorJob()
修复该问题后,您的代码将在 UI 线程上进行阻塞调用。要在后台线程上进行阻塞调用,但仍将协程的其余部分保留在 UI 线程上,请编写
uiScope.launch {
try {
text.text = withContext(Dispatchers.IO) {
URL("https://httpbin.org/get").readText()
}
} catch (e: Exception) {
text.text = e.message
} finally {
log(this@MainActivity, result)
}
}
我找到了解决方案。我无法从另一个线程访问 UI 组件,同时我无法在主线程上进行互联网请求。所以我应该选择其中之一。解决方案是使用 ViewModel 组件并更新它的 LiveDate 值,该值随后将更改 UI
var viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
viewModel.selected.observe(this, Observer{ users ->
text.text = users
})
uiScope.launch {
try {
result = URL("http://jsonplaceholder.typicode.com/posts").readText()
viewModel.selected.postValue(result)
} catch (error: Error) {
viewModel.selected.postValue(error.toString())
}
}
log(this@MainActivity,result)
我正在尝试使用协程向后端发出简单请求
uiScope.launch {
try {
result = URL("https://httpbin.org/get").readText()
text.text = result
} catch (error: Error) {
text.text = error.message
} finally {
log(this@MainActivity,result)
}
}
但是抛出了这个异常:
android.view.ViewRootImpl$CalledFromWrongThreadException
: Only the original thread that created a view hierarchy can touch its views.
如何解决?
您的 uiScope
设置不正确,显然它的调度程序不是 Dispatchers.Main
。所以首先要修复的是 coroutineContext
属性 的实现,它应该是
override val coroutineContext = Dispatchers.Main + SupervisorJob()
修复该问题后,您的代码将在 UI 线程上进行阻塞调用。要在后台线程上进行阻塞调用,但仍将协程的其余部分保留在 UI 线程上,请编写
uiScope.launch {
try {
text.text = withContext(Dispatchers.IO) {
URL("https://httpbin.org/get").readText()
}
} catch (e: Exception) {
text.text = e.message
} finally {
log(this@MainActivity, result)
}
}
我找到了解决方案。我无法从另一个线程访问 UI 组件,同时我无法在主线程上进行互联网请求。所以我应该选择其中之一。解决方案是使用 ViewModel 组件并更新它的 LiveDate 值,该值随后将更改 UI
var viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
viewModel.selected.observe(this, Observer{ users ->
text.text = users
})
uiScope.launch {
try {
result = URL("http://jsonplaceholder.typicode.com/posts").readText()
viewModel.selected.postValue(result)
} catch (error: Error) {
viewModel.selected.postValue(error.toString())
}
}
log(this@MainActivity,result)