Akshdeep Singh
Akshdeep Singh

Reputation: 1457

Android waiting for listener freezing the app?

I want to show a progress dialog and dismiss it after the onCompleteListener has responded as follows:

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
            }
    }

}

But the above code freezes the app.

If I comment the while loop and dismiss dialog code as:

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

the progress dialog shows forever.

So, why is the while loop freezing the app?

Even if the value of processCompleted never becomes true, I think it should result in progress bar being running forever rather than freezing the app.

But even the progress dialog doesn't show up because of while loop and the button which shows the dialog remains clicked and the app gets freezed, why?

Upvotes: 0

Views: 331

Answers (1)

Bill
Bill

Reputation: 400

That's because onCreateDialog runs on the system's UI thread - meaning the UI can't update while something is running.

The solution is to move the code to dismiss the dialog to a separate thread - your completion listener seems like the perfect place!

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
        }
}

Upvotes: 1

Related Questions