android - 不阻塞将查询结果返回到主线程
问题描述
我在使用 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
}
推荐阅读
- android - 是否可以在不生根设备的情况下以编程方式触摸屏幕上的事件?
- c++ - 具有对齐存储的动态内存分配
- java - java.lang.IllegalArgumentException:非法 base64 字符 -1
- angular - 从可观察的角度 7 中获取最后发出的值
- reactjs - 如何在 React 中的套接字事件后删除数组中的元素?
- android - 应用程序关闭时在后台检查互联网连接
- php - 使用 laravel 查询获取错误的 ID
- angular - Angular div 删除动画
- testing - 如何合并elixir伞app的测试报告?
- node.js - Node js 承诺异步/等待