You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非Activity类创建Dialog触发android.view.WindowManager$BadTokenException问题

Fixing WindowManager$BadTokenException When Showing Dialog from Non-Activity Class

Hey there! Let's break down why you're hitting this frustrating exception and walk through how to fix it.

What's Causing the Error?

That BadTokenException almost always stems from one of two issues:

  • You’re using a non-Activity Context (like ApplicationContext) to create the dialog. Dialogs need to attach to an Activity’s window, and the app context doesn’t have its own window to bind to.
  • The target Activity (Activity A in your scenario) isn’t in an active state when you try to show the dialog. When you press back from Activity B, Activity A might be in the middle of lifecycle transitions (like restarting) or could even be marked as finishing.

Step-by-Step Fixes

1. Use a Valid Activity Context

First, make sure when you call ShowDialogBox, you pass Activity A’s instance (using this) instead of any other Context type. Never use getApplicationContext() here—dialogs rely on an Activity’s window to display properly.

2. Check Activity's Active State Before Showing the Dialog

Before triggering the dialog, verify that Activity A is still alive and not finishing. Add this check in Activity A where you call your dialog method:

if (!this.isFinishing() && !this.isDestroyed()) {
    YourNonActivityClass.ShowDialogBox(this, yourListenerInstance);
}

3. Fix the Syntax Error in Your Dialog Code

Looking at your code, there’s a small syntax mistake in the setPositiveButton call that could cause unexpected behavior. Here’s the cleaned-up, corrected version:

public static void ShowDialogBox(final Context con, final Listener list) {
    // First confirm we're working with an Activity context
    if (!(con instanceof Activity)) {
        return; // Exit early if context isn't an Activity
    }

    final Activity activity = (Activity) con;
    // Ensure dialog runs on the main thread (UI operations can't run on background threads)
    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            AlertDialog.Builder dlgAlert = new AlertDialog.Builder(activity);
            dlgAlert.setMessage("TEXT");
            dlgAlert.setTitle("TEXT");
            dlgAlert.setPositiveButton("TEXT", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    // Trigger your listener callback here if needed
                    if (list != null) {
                        // list.onYourListenerMethod();
                    }
                }
            });
            dlgAlert.setCancelable(false);
            
            AlertDialog dialog = dlgAlert.create();
            // Double-check Activity state before showing to avoid exceptions
            if (!activity.isFinishing() && !activity.isDestroyed()) {
                dialog.show();
            }
        }
    });
}

Key improvements here:

  • Fixed the misplaced parenthesis in setPositiveButton
  • Wrapped dialog creation in runOnUiThread to ensure it runs on the main thread (critical for UI operations)
  • Added checks to confirm the context is an Activity, and that the Activity is still active before showing the dialog

4. Verify Listener Callback Timing

Make sure your listener from Activity B triggers the dialog call after Activity A has resumed. If Activity A is still in onRestart or onStart when the callback hits, it might not be ready to display UI elements. You can post the dialog call to the Activity’s message queue to ensure it runs after the lifecycle is complete:

// In Activity A's listener callback
activity.post(new Runnable() {
    @Override
    public void run() {
        if (!activity.isFinishing() && !activity.isDestroyed()) {
            YourNonActivityClass.ShowDialogBox(activity, yourListener);
        }
    }
});

Final Notes

Always remember that dialogs are tightly coupled to an Activity’s lifecycle. Any time you show a dialog from outside an Activity, you need to guarantee that the target Activity is in a valid state to display UI.

内容的提问来源于stack exchange,提问作者Rajesh K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:05:40