如果我使用协程在Android中读/写Realm以避免阻塞UI,是否还需要使用后台线程?

我脑子里有问题,我不知道如何测试。

假设我有一个函数getData,该函数从一个领域对象中加载数据,这需要5秒钟。

没有协程,我需要在后台线程中调用此方法,以避免阻塞UI。

如果我将getData更改为暂停功能,并在主线程上调用它,它还会冻结UI线程5秒钟吗?还是就像在getData函数中调用delay(5000)一样,不会阻塞UI线程?

我想创建一个简单的项目来验证这一点,但是我没有足够大的数据来产生5秒的延迟。

xieyijin 回答:如果我使用协程在Android中读/写Realm以避免阻塞UI,是否还需要使用后台线程?

  

如果我将getData更改为suspend函数,并在主线程上调用它,它还会冻结UI线程5秒钟吗?

是的,协程不能撤消给定代码段进行阻塞函数调用的事实。这是典型的惯用语,您可以用来将对后台线程的阻塞调用移开,然后继续在UI线程上使用它:

myScope.launch {
    val result = withContext(Dispatchers.IO) {
        // blocking call here
    }
    // use the result to update the GUI here
}
,

我认为这取决于您的意思

如果我将getData更改为暂停功能

  • 如果仅在函数中添加关键字suspend,它将什么都不会改变,即线程将被阻塞,直到得到响应为止。
  • 如果您将功能重写为“可暂停”,则它将
    1. 触发请求
    2. 暂停自身(不阻塞线程)
    3. 收到回复后恢复

您可以使用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
    }

P.S。上面的情况(从db中获取数据)可能无法工作,因为没有任何要挂起的功能(与网络请求不同,功能一直很忙)。

本文链接:https://www.f2er.com/3086762.html

大家都在问