Kotlin:顺序协程的结构

问题描述 投票:0回答:1

我正在为Android构建一个库管理器应用程序,我正在尝试构建一个视图,以显示从当前集合到根目录的“集合”(即文件夹)的层次结构。

数据库使用Room实现(通过collectionRepo间接访问)。每个Collection对象都有一个唯一的密钥,并且知道其父密钥。

我正在尝试做什么:

  1. 给定当前集合的密钥,将集合层次结构构建为root。
  2. 完成此操作后,构建层次结构的UI呈现。

对于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
android kotlin android-room kotlinx.coroutines kotlin-coroutines
1个回答
0
投票

请检查下一个代码,它应该对您有所帮助:

    // 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'
© www.soinside.com 2019 - 2024. All rights reserved.