繁体   English   中英

将查询结果返回主线程而不会阻塞

[英]Return query results to main thread without blocking

我在使用Kotlin协程时遇到麻烦,正在尝试查询数据库并将结果返回到主线程,但是我不知道如何在不“冻结”主线程的情况下做到这一点。 在这种情况下,runBlocking将是罪魁祸首,但是我不确定该用什么代替它。 任何帮助都将不胜感激!

fun getResults() : List<String> {
    val results = ArrayList<String>()

    runBlocking {
        viewModelScope.launch(Dispatchers.IO) {
            openConnection()

            try {
                statement = connection!!.createStatement()
                resultSet = statement!!.executeQuery("blah blah blah")
                while (resultSet != null && resultSet!!.next()) {
                    results.add(resultSet!!.getString(1))
                }
            } catch (e: Exception) {
                Log.d("getList Catch", e.toString())
            }

            closeConnection()
        }.join()
    }

    return results
}

当与可暂停的协程或回调一起适当地确定阻塞任务的范围时,不需要runBlocking

如前所述,您有几个选择:

悬浮的协程

suspend fun getResults() : List<String> = suspendCancellableCoroutine { cont ->

    openConnection()

    val results = ArrayList<String>()

    try {
        statement = connection!!.createStatement()
        resultSet = statement!!.executeQuery("blah blah blah")
        while (resultSet != null && resultSet!!.next()) {
            results.add(resultSet!!.getString(1))
        }
        closeConnection()
        cont.resumeWith(Result.success(results))
    } catch (e: Exception) {
        Log.d("getList Catch", e.toString())
        closeConnection()
        cont.resumeWith(Result.failure(e))
    }
}

匿名回调

fun getResults(cb: (List<String>) -> Unit) {
    viewModelScope.launch(Dispatchers.IO) {
        openConnection()

        val results = ArrayList<String>()

        try {
            statement = connection!!.createStatement()
            resultSet = statement!!.executeQuery("blah blah blah")
            while (resultSet != null && resultSet!!.next()) {
                results.add(resultSet!!.getString(1))
            }
        } catch (e: Exception) {
            Log.d("getList Catch", e.toString())
        }
        cb.invoke(results)
        closeConnection()
    }
}

我个人的偏爱是第二种选择,因为它消除了方法使用者必须了解和实现可挂起的需求。

launch(Dispatchers.IO) {
   val results = getResults()
   // handle results
}

getResults {
   // handle results
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM