我脑子里有个问题,我不知道怎么测试它。
假设我有一个函数getData,它从一个领域对象加载数据,耗时5秒。
如果没有协同,我需要在后台线程中调用此方法,以避免阻塞UI。
如果我将getData更改为挂起函数,并在主线程上调用它,它还会冻结UI线程5秒吗?还是像调用getData函数中的延迟(5000)一样,不会阻塞UI线程?
我想创建一个简单的项目来验证这一点,但是我没有足够大的数据来产生5秒的延迟。
发布于 2019-11-17 14:18:31
如果我将
getData更改为suspend函数,并在主线程上调用它,它还会冻结UI线程5秒吗?
是的,coroutines无法撤销给定代码进行阻塞函数调用的事实。这是典型的成语,您可以使用它向后台线程传递阻塞调用,然后在UI线程上继续使用它:
myScope.launch {
val result = withContext(Dispatchers.IO) {
// blocking call here
}
// use the result to update the GUI here
}发布于 2020-01-08 12:46:40
我想这取决于你的意思
如果我将
更改为挂起函数,则为
getData
如果将关键字suspend添加到函数中,则不会发生任何更改,即线程将被阻塞,直到得到响应为止。如果您重写函数为“可挂起的”,那么它将触发request
之后不阻塞thread)
您可以使用Coroutines库中的suspendCoroutine函数来实现这一点。
抽象示例可以如下所示:
suspend fun getData(): String = suspendCoroutine { continuation ->
// 1. Trigger event
serverApi.getData().onResult(
// 3. Resume either with data or error, after callback received from serverApi
onSuccess = {
continuation.resume("Data")
},
onError = {
continuation.resume("Error")
}
)
// 2. Suspend after block is finished
}在您的情况下(从db获取数据)可能无法工作,因为没有什么可挂起的(函数一直很忙,与网络请求不同)。
https://stackoverflow.com/questions/58899960
复制相似问题