我正在尝试通过协程简单地请求后端
const originalConsoleLog = console.log;
console.log = function() {
// extract log message and save somewhere to be shown in DOM
originalConsoleLog.apply(this, arguments)
}
但会抛出此异常:
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) } }
:只有创建视图层次结构的原始线程才能触摸其视图。
如何解决?
答案 0 :(得分:0)
您的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)
}
}
答案 1 :(得分:0)
我找到了解决方案。我无法从另一个线程访问UI组件,同时无法在主线程上发出Internet请求。所以我应该搬家之一。解决方案是使用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)