使用协程实现弹窗队列

79 阅读1分钟

一、功能样式

image.png

原链接:juejin.cn/post/727594…

这个看起来其实是很好的,但是实际使用却有很多限制,只能在一个协程下使用,并且没有优先级,但是确实是一个好的思路,打开了我的思路。

二、更新版本

object MutexExt {

    private val mutex = Mutex()

    private var scope = createNewScope()

    private val mutexQueue = PriorityQueue<MuteTask>()

    fun initMute() {
        if (scope.isActive) {
            processTask()
        } else {
            scope = createNewScope() // Recreate the scope if it was cancelled
            processTask()
        }
    }

    private fun createNewScope(): CoroutineScope {
        return CoroutineScope(SupervisorJob() + Dispatchers.IO)
    }

    fun destroy() {
        scope.cancel()
    }

    /**
     * 当 task 结束后,需要调用
     * */
    fun addMutexTask(block: suspend () -> Unit) {
        scope.launch(CoroutineExceptionHandler { _, exception ->
            Log.d("KtvMutexExt", "CoroutineExceptionHandler got $exception")
        }) {
            mutex.withLock {
                block()
            }
        }
    }


    private fun addDialog(priority: Int, block: suspend () -> Unit) {
        mutexQueue.offer(MuteTask(priority, block))
    }

    private fun processTask() {
        scope.launch {
            while (mutexQueue.isNotEmpty()) {
                val task = mutexQueue.poll()
                mutex.withLock {
                    task.block()
                }
            }
        }
    }

    suspend fun showDemoDialog(
        context: Context,
        title: String,
        content: String,
        buttonText: String
    ) =
        suspendCancellableCoroutine { continuation ->
            MaterialAlertDialogBuilder(context)
                .setTitle(title)
                .setMessage(content)
                .setPositiveButton(buttonText) { dialog, which ->
                    dialog.dismiss()
                }
                .setOnDismissListener {
                    continuation.resume(Unit)
                }
                .show()
        }

    private data class MuteTask(
        val priority: Int,
        val block: suspend () -> Unit
    ) : Comparable<MuteTask> {
        override fun compareTo(other: MuteTask): Int {
            return other.priority.compareTo(this.priority) // Higher priority first
        }
    }
}

对之前功能进行了优化,现在增加了权重的概念,并且增加了mutex。但是感觉这么写完,其实对实际业务也没有太大大提升。做次记录吧。