我在使用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
}
答案 0 :(得分:1)
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
}
vs。
getResults {
// handle results
}