我正在为Android构建一个库管理器应用程序,我正在尝试构建一个视图,以显示从当前集合到根目录的“集合”(即文件夹)的层次结构。
数据库使用Room实现(通过collectionRepo间接访问)。每个Collection对象都有一个唯一的密钥,并且知道其父密钥。
我正在尝试做什么:
对于Kotlin的协同程序来说,这看起来应该非常简单,但是我还没有能够正确地设置协同程序。
由于每次调用collectionRepo.getCollection(curKey)
最终都会进行Room db查询,因此它必须脱离主线程。但我需要等待查询返回,以便知道后续查询所需的parentKey。
private suspend fun buildBackstackView() {
var curKey = collectionViewModel.getCurrentCollectionKey()
coroutineScope {
launch {
do {
val curCollection = when (curKey) {
"" -> {
Collection("", 0, "TOP", "") // collection's parent is root - create a fake root Collection to push to the stack
}
else -> {
collectionRepo.getCollection(curKey) // ultimately a Room database query
}
}
collectionStack.add(curCollection)
curKey = curCollection.key
} while (curKey != "")
}
}
withContext(Dispatchers.Main) {
...build UI view using collectionStack...
}
}
响应Sergey的请求,collectionRepo.getCollection()只是将请求传递给定义Room查询的DAO方法。
@Query("SELECT * FROM collections WHERE `key` = :colKey LIMIT 1")
fun getCollection(colKey: String): Collection
请检查下一个代码,它应该对您有所帮助:
// creating local scope for coroutines
private var job: Job = Job()
private val scope = CoroutineScope(Dispatchers.Main + job)
// call this to cancel job when you don't need it anymore, for example in Activity.onDestroy() method
fun cancelJob() {
job.cancel()
}
private fun buildBackstackView() {
var curKey = collectionViewModel.getCurrentCollectionKey()
scope.launch {
do {
val curCollection = when (curKey) {
"" -> {
Collection("", 0, "TOP", "")
}
else -> withContext(Dispatchers.IO) { // runs in background thread suspending the coroutine
collectionRepo.getCollection(curKey)
}
}
collectionStack.add(curCollection)
curKey = curCollection.key
} while (curKey != "")
// ...build UI view using collectionStack...
}
}
要使用Dispatchers.Main导入:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'