Android ждет, когда слушатель заморозит приложение? - PullRequest
0 голосов
/ 16 июня 2019

Я хочу показать диалог прогресса и закрыть его после того, как 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 останавливает приложение?

Даже если значение processCompleted никогда не станет true, я думаю, это должно привести к тому, что индикатор выполнения будет работать вечно, а не зависать в приложении.

Но даже прогресс dialog не отображается, потому чтоцикла while и кнопка, которая показывает dialog, остается нажатой, и приложение зависает, почему?

1 Ответ

1 голос
/ 16 июня 2019

Это потому, что onCreateDialog выполняется в системном потоке пользовательского интерфейса - это означает, что пользовательский интерфейс не может обновляться во время выполнения чего-либо.

Решение состоит в том, чтобы переместить код, чтобы закрыть диалоговое окно, в отдельный поток - вашслушатель завершения кажется идеальным местом!

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
        }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...