首页 > 解决方案 > Android 等待侦听器冻结应用程序?

问题描述

我想显示一个进度对话框并在onCompleteListener响应如下后将其关闭:

class DialogSubjectsAdd: DialogFragment() {

    private val db = FirebaseFirestore.getInstance().collection("courses")
    private var docFetched = false
    private var processCompleted = false

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        super.onCreateDialog(savedInstanceState)

        getCoursesIndexDoc()
        // show progress dialog

        // wait until download operation is completed
        while (!processCompleted) {}
        // dismiss dialog

        // todo

    }

    private fun getCoursesIndexDoc() {
        // fetch the index document
        db.document("all")
            .get()
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    docFetched = true
                }
                processCompleted = true
            }
    }

}

但是上面的代码冻结了应用程序。

如果我将循环注释while并关闭对话框代码为:

// while (!processCompleted) {}
// // dismiss dialog

进度对话框永远显示。

那么,为什么while循环会冻结应用程序?

即使processCompletednever 的值变为true,我认为它应该导致进度条永远运行而不是冻结应用程序。

但是由于循环和显示剩余点击的按钮并且应用程序被冻结,即使是进度dialog也没有显示,为什么?whiledialog

标签: androidkotlinlistener

解决方案


那是因为onCreateDialog在系统的 UI 线程上运行 - 这意味着 UI 在某些东西运行时无法更新。

解决方案是移动代码以将对话框关闭到单独的线程 - 您的完成侦听器似乎是完美的地方!

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    super.onCreateDialog(savedInstanceState)

    getCoursesIndexDoc()
    // Don't do anything else here!
}

private fun getCoursesIndexDoc() {
    // fetch the index document
    db.document("all")
        .get()
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                docFetched = true
            }
            // Instead of setting the flag, dismiss the dialog here
        }
}

推荐阅读