Resolving android.view.WindowManager$BadTokenException in AsyncTask.onPostExecute

Dec 07, 2025 · Programming · 12 views · 7.8

Keywords: Android | WindowManager | BadTokenException | AsyncTask | AlertDialog | isFinishing | WeakReference

Abstract: This article analyzes the WindowManager$BadTokenException that occurs when displaying AlertDialog from AsyncTask.onPostExecute in Android. It explains window tokens, risks of UI updates from background threads, and provides solutions using isFinishing() and weak references, with code examples and best practices to prevent crashes.

In Android development, displaying UI elements like AlertDialog from background threads, such as in AsyncTask's onPostExecute, can lead to the android.view.WindowManager$BadTokenException, causing unexpected application crashes. This exception typically occurs when the associated Activity has finished or is finishing, and the WindowManager cannot add a new window.

Analyzing the Cause of the Exception

The BadTokenException stems from the invalid use of window tokens. Window tokens are Binder tokens used by the WindowManager to uniquely identify windows in the system, ensuring secure inter-app interactions. When an Activity enters a finishing state (e.g., user presses back button, finish() is called, or system cleanup), its window token becomes invalid. Attempting to add a window using this token from a background thread, such as showing a dialog, results in the WindowManager rejecting the request and throwing the exception.

In AsyncTask's onPostExecute method, code often runs to update the UI after background work, but if the Activity is destroyed, dialogs with invalid contexts cannot attach to a window, triggering crashes.

Solution: Using isFinishing() and Weak References

To avoid this exception, verify the Activity state before performing UI operations. Android provides the isFinishing() method, which returns true if the Activity is in the process of finishing. Combined with weak references (WeakReference) to store Activity references, this prevents memory leaks while allowing safe access.

Weak references enable garbage collection of the Activity when no longer needed, and in onPostExecute, checking that the weak reference is non-null and the Activity is not finishing ensures safe dialog display.

Code Example and Implementation

Based on the code from the question, here is an improved version:

private class chkSubscription extends AsyncTask<String, Void, String>{

  private final WeakReference<login> loginActivityWeakRef;

  public chkSubscription (login loginActivity) {
    super();
    this.loginActivityWeakRef = new WeakReference<login>(loginActivity);
  }

  protected String doInBackground(String... params) {
    // web service call
  }

  protected void onPostExecute(String result) {
    if (page.contains("error")) {
      if (loginActivityWeakRef.get() != null && !loginActivityWeakRef.get().isFinishing()) {
        AlertDialog.Builder builder = new AlertDialog.Builder(login.this);
        builder.setCancelable(true);
        builder.setMessage("");
        builder.setInverseBackgroundForced(true);
        builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int whichButton) {
            dialog.dismiss();
            // additional logic
          }
        });
        builder.show();
      }
    }
  }
}

In this code, the WeakReference holds the Activity instance, and onPostExecute checks reference validity and Activity state before creating and showing the AlertDialog.

Understanding Window Tokens

Window tokens are not just technical details but core to Android's security model. They prevent malicious applications from drawing over other apps' windows. When an app starts, the ActivityManagerService creates an application window token as a unique identifier for the top-level container window. Each time the app adds a window, it must pass this token for validation; mismatches cause BadTokenException.

For instance, in real-world scenarios, the activity manager collaborates with the window manager to ensure legitimate window addition requests via tokens, enhancing system security against unauthorized access.

Conclusion and Best Practices

Best practices for handling BadTokenException include always checking the Activity lifecycle state before updating UI from background threads using isFinishing(), employing weak references to avoid memory leaks, and adhering to Android's lifecycle guidelines for robust code. By implementing these measures, developers can significantly reduce crash risks and improve application stability.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.