What a ProgressDialog is and why you need to dismiss it

A ProgressDialog is a box that appears on your Android phone screen to show that something is loading or processing — usually a spinning circle or progress bar with a message like "Loading..." or "Please wait." It blocks interaction with the rest of the app until the task finishes. Once the task is done, you need to close (or "dismiss") that dialog box so the user can see the result or continue using the app.

If you do not dismiss the ProgressDialog when the task completes, the box stays on screen indefinitely, freezing the app's interface. This is one of the most common problems in Android development, especially when working with network requests, file uploads, or database operations that take time. The dialog will remain visible until you explicitly call the dismiss method or the activity is destroyed.

Key Takeaways

  • Call progressDialog.dismiss() when the background task finishes to close the dialog box when ready.
  • Always dismiss the dialog in the callback or completion method of your background operation, not in the main thread before the work is done.
  • Use a null check like if (progressDialog != null && progressDialog.isShowing()) before dismissing to prevent crashes if the dialog was already closed.
  • For modern Android projects, consider using ProgressBar or ProgressIndicator instead of ProgressDialog, since ProgressDialog is deprecated in newer Android versions.

The basic dismiss() method

The simplest way to close a ProgressDialog is to call the dismiss() method on your dialog object. If your ProgressDialog is stored in a variable called progressDialog, you write:

progressDialog.dismiss();

This removes the dialog from the screen when ready. However, you must call this method at the right time — after the background task finishes, not before. If you dismiss the dialog before the work is complete, the user will see the result appear without any indication that loading was happening.

The dismiss method works on any ProgressDialog instance, regardless of how you created it or what message it displays. Once called, the dialog is gone and cannot be shown again without creating a new instance.

Dismissing after a network request or database operation

The most common scenario is dismissing a ProgressDialog after a network call or database query finishes. If you are using a callback or listener, dismiss the dialog inside that callback:

progressDialog.show(); apiService.fetchData(new Callback<Response>() {   @Override   public void onResponse(Call<Response> call, Response<Response> response) {     progressDialog.dismiss();     // Handle the response   }   @Override   public void onFailure(Call<Response> call, Throwable t) {     progressDialog.dismiss();     // Handle the error   } });

Notice that dismiss() is called in both onResponse() and onFailure(). This ensures the dialog closes whether the request succeeds or fails. If you only dismiss on success, a failed request will leave the dialog stuck on screen.

The same pattern applies to database operations, file uploads, or any other background work. Place the dismiss call in the completion handler, not in the code that starts the operation.

Using null checks to prevent crashes

A common crash occurs when you try to dismiss a dialog that no longer exists or was already closed. This can happen if the user navigates away from the screen before the background task finishes, or if the dialog was garbage collected. To prevent this, always check that the dialog exists and is showing before dismissing:

if (progressDialog != null && progressDialog.isShowing()) {   progressDialog.dismiss(); }

The isShowing() method returns true only if the dialog is currently visible on screen. This check prevents crashes from trying to dismiss a dialog that was already closed or never created. Without this guard, your app may throw an exception and crash when the background task completes after the user has left the screen.

Dismissing when the user cancels

You can also let users close the ProgressDialog themselves by setting it as cancellable. When you create the dialog, call setCancelable(true):

progressDialog.setCancelable(true); progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {   @Override   public void onCancel(DialogInterface dialog) {     // Stop the background task or handle cancellation   } });

When the user presses the back button or taps outside the dialog, the onCancel() method runs. You can use this to stop the background operation or log that the user cancelled. The dialog dismisses automatically when cancelled, so you do not need to call dismiss() in the cancel listener.

Modern alternatives to ProgressDialog

ProgressDialog is deprecated in Android API 26 and later, meaning Google no longer recommends using it for new apps. Instead, use a ProgressBar in your layout file or a ProgressIndicator from the Material Design library. These are more flexible and fit better with modern Android design.

If you are using a ProgressBar, you hide and show it by changing its visibility instead of dismissing a dialog:

progressBar.setVisibility(View.VISIBLE); // Show progressBar.setVisibility(View.GONE); // Hide

This approach avoids the crashes and complexity of managing dialog lifecycles. ProgressBar is part of your activity layout, so it lives and dies with the activity itself. If you are starting a new project, use ProgressBar or Material ProgressIndicator rather than ProgressDialog.

Frequently Asked Questions

What is the difference between dismiss() and cancel()?

dismiss() closes the dialog without triggering any cancel listener. cancel() closes the dialog and calls the OnCancelListener if one is set. Use dismiss() when the task completes normally, and cancel() when the user or app stops the operation early.

Why does my app crash when I try to dismiss the ProgressDialog?

The dialog was likely already closed or the activity was destroyed before dismiss() was called. Always use a null check and isShowing() before dismissing. Also check that you are calling dismiss() on the main thread, not a background thread.

Can I dismiss a ProgressDialog from a background thread?

No. You must call dismiss() on the main thread. If your background task finishes on a worker thread, use runOnUiThread() or a Handler to post the dismiss call back to the main thread before executing it.

Should I still use ProgressDialog in new Android projects?

No. ProgressDialog is deprecated and removed from newer Android versions. Use a ProgressBar or Material ProgressIndicator in your layout instead. They are easier to manage and follow current Android design guidelines.