如果 kotlin 协程作业需要相当长的时间才能完成,如何有效地显示加载对话框?

Ash*_*shu 5 android kotlin kotlin-coroutines

我想要做的是使用 kotlin 协程进行数据库操作,同时向用户显示加载屏幕。我的基本实现如下:

fun loadSomeData(){
    mainCoroutineScope.launch { 
        showLoadingDialog()
        // suspening function over Dispatchers.IO, returns list
        val dataList = fetchDataFromDatabase()
        inflateDataIntoViews(dataList)
        hideLoadingDialog()
    }
}
Run Code Online (Sandbox Code Playgroud)

当大型数据集的加载需要相当长的时间时,这对我来说非常有效。但是在fetchDataFromDatabase()快速完成的情况下,快速连续显示和隐藏对话框会产生令人讨厌的故障效果。

所以,我要的是显示该对话框只有在fetchDataFromDatabase()功能需要超过,可以说,100毫秒内完成。

所以我的问题是,使用 kotlin 协程实现这一目标的高效方法什么?

Ash*_*shu 3

!!以下是我在不使用非空运算符的情况下实现这一目标的方法:

val deferred = lifecycleScope.async(Dispatchers.IO) {
    // perform possibly long running async task here
}

lifecycleScope.launch (Dispatchers.Main){
    // delay showing the progress dialog for whatever time you want
    delay(100)

    // check if the task is still active
    if (deferred.isActive) {

        // show loading dialog to user if the task is taking time
        val progressDialogBuilder = createProgressDialog()

        try {
            progressDialogBuilder.show()

            // suspend the coroutine till deferred finishes its task
            // on completion, deferred result will be posted to the
            // function and try block will be exited.
            val result = deferred.await()
            onDeferredResult(result)

        } finally {
            // when deferred finishes and exits try block finally
            // will be invoked and we can cancel the progress dialog
            progressDialogBuilder.cancel()
        }
    } else {
        // if deferred completed already withing the wait time, skip
        // showing the progress dialog and post the deferred result
        val result = deferred.await()
        onDeferredResult(result)
    }
}
Run Code Online (Sandbox Code Playgroud)