I was trying to learn about coroutines and how long processes should be handled on a different thread rather than the main UI thread. I thought of adding a please wait dialog when the process starts and when the background process completes, the please wait dialog disappears.
The problem is when I call dismiss() some weird glitch happens and the whole layout becomes frozen like shown in the images. Also, when the custom dialog appears, note that only background should be "darkened" but instead the please wait dialog also gets darkened. The following is the code and screenshots from the AVD.
In the images below, please ignore the "Execute a long task" Button.
package android.development.myfirstapp
import android.app.Dialog
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.*
class CoroutinesActivity : AppCompatActivity() {
private var progressDialog: Dialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_coroutines)
val btnBackgroundTask = findViewById<Button>(R.id.btnBackgroundTask)
btnBackgroundTask.setOnClickListener {
showCustomProgressDialog()
lifecycleScope.launch{
backgroundTask("Task Executed Successfully")
}
}
}
private suspend fun backgroundTask(result: String) {
withContext(Dispatchers.IO){
for (i in 1..100000) {
Log.e("delay :", i.toString())
}
runOnUiThread {
dismissProgressDialog()
Toast.makeText(this@CoroutinesActivity, result, Toast.LENGTH_SHORT).show()
}
}
}
private fun showCustomProgressDialog() {
progressDialog = Dialog(this@CoroutinesActivity)
with(progressDialog){
setContentView(R.layout.progress_dialog)
window?.setBackgroundDrawableResource(android.R.color.transparent)
this?.setCanceledOnTouchOutside(false)
this?.show()
}
}
private fun dismissProgressDialog() {
if (progressDialog != null && progressDialog!!.isShowing){
progressDialog?.dismiss()
progressDialog = null
}
}
}
The following is the XML file of the please wait dialog.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<!--
<ProgressBar
android:layout_width="150dp"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:progress="25"
android:secondaryProgress="50"
/>
-->
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="Please Wait..."/>
</LinearLayout>
The following is the XML file of the activity.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CoroutinesActivity">
<Button
android:id="@+id/btnLongTask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Execute a long task"
app:layout_constraintBottom_toTopOf="@id/btnBackgroundTask"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btnBackgroundTask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Execute a Background Task"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnLongTask" />
</androidx.constraintlayout.widget.ConstraintLayout>
The following picture is of when the long task is executed, i.e., "Execute a background task" button us clicked.
The following is when the background task has ended and the screen freezes.
How do I fix this so the dialog executes when I run the background task and it dismisses when I call dismiss() and not do this glitch.
Edit :
I found a temporary solution by making our variable progressDialog non-nullable and adding lateinit modifier in front (also removed progressDialog?.anyOperation() cases) and now the code works just fine. But, my question is why does the Dialog class have soo much problem with being nullable even if it isn't null? Does anyone have any answer to this?

