[英]How to cancel kotlin coroutine if it takes longer than a certain period of time?
[英]How to efficiently show loading dialog if kotlin coroutine job takes quite some time to complete?
我想做的是使用 kotlin 協程進行數據庫操作,同時向用戶顯示加載屏幕。 我的基本實現如下:
fun loadSomeData(){
mainCoroutineScope.launch {
showLoadingDialog()
// suspening function over Dispatchers.IO, returns list
val dataList = fetchDataFromDatabase()
inflateDataIntoViews(dataList)
hideLoadingDialog()
}
}
當加載大型數據集需要相當長的時間時,這對我來說非常有效。 但是在fetchDataFromDatabase()
快速完成的情況下,快速連續顯示和隱藏對話框會產生煩人的故障效果。
所以我想要的是僅當fetchDataFromDatabase()
function需要超過 100 毫秒才能完成時才顯示對話框。
所以我的問題是,使用 kotlin 協程實現這一目標的高效方法是什么?
這是一個想法:
fun loadSomeData(){
mainCoroutineScope.launch {
val dialogJob = launch {
delay(1000)
try {
showLoadingDialog()
coroutineContext.job.join()
} finally {
hideLoadingDialog()
}
}
val dataList = fetchDataFromDatabase()
inflateDataIntoViews(dataList)
dialogJob.cancel()
}
}
當您取消dialogJob
時,它應該點擊delay
語句並阻止顯示對話框,或者join
語句,這將導致finally
塊執行並隱藏它。
這是我在不使用的情況下實現這一目標的方法!!
不是 null 運算符:
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)
}
}
加載對話框的主要目的是防止用戶在加載時觸摸 UI,但不能保證這一點。 在對話框彈出之前,用戶總是有機會觸摸某個按鈕。
更好的方法是禁用或隱藏 UI 組件,或者通常顯示 UI 的“加載版本”。
最好讓用戶取消加載而不是設置一個短暫的超時,因此您可能仍然需要一個顯示取消按鈕的對話框或小吃欄,或者您可以在您的應用程序中創建一個任務管理器頁面,但這確實很復雜。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.