AlertDialog.Builder#show 上的“android.view.WindowManager$BadTokenException”即使有保护措施

Posted

技术标签:

【中文标题】AlertDialog.Builder#show 上的“android.view.WindowManager$BadTokenException”即使有保护措施【英文标题】:"android.view.WindowManager$BadTokenException" on AlertDialog.Builder#show even with safeguards 【发布时间】:2018-10-02 08:45:50 【问题描述】:

我收到了android.view.WindowManager$BadTokenException 异常,即使在对话框的创建和显示周围有(我理解为所有必要的)安全措施。

下面是创建和显示对话框的代码:

public class MyFragmentActivity extends FragmentActivity

    public void handleErrorDialogOk() 
        ...
    

    public void makeErrorDialog()
        if (!isFinishing())
            runOnUiThread(new Runnable()
            
                @Override
                public void run()
                
                    if (isFinishing())
                        return;

                    new AlertDialog.Builder(MyFragmentActivity.this)
                        .setTitle("Some title")
                        .setMessage("Some message")
                        .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() 
                            public void onClick(DialogInterface dialog, int which) 
                                handleErrorDialogOk();
                            
                        )
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .show();
                
            );

        
    

我没有一直看到它,它似乎是随机的,我无法重现它(只能在已发布应用的 Play 商店的 ANRs & crashes 选项卡中看到它)。

我在这里做错了吗?

或者这可能是FragmentActivity 的错误?我似乎没有看到任何AlertDialogs 出现这种情况,这些AlertDialogs 是从派生自标准Activity 类的类的实例中呈现的......

【问题讨论】:

【参考方案1】:

当您尝试在 Activity 中创建对话框时发生异常,但 Activity 已经完成。该窗口不再可用。因此,更改上下文:

 if(!context.isFinishing()) 
 //FragmentActivity is the context
  builder.show();
  

【讨论】:

但我已经在检查呈现上下文是否未完成,无论是在发布到主线程之前,还是在实际显示对话框之前【参考方案2】:

在进一步检查 Play 商店崩溃/ANR 数据后,我注意到这只发生在特定的 Android 版本上;正如我最初在我的问题中所指出的,它只发生在派生自FragmentActivity 的类上,这使我得出结论,该Android 版本的FragmentActivity impl 中一定存在某种错误,因为我正在采取所有预防措施我理解有必要避免在破坏活动上显示对话框(这是此异常的常见原因)。

【讨论】:

以上是关于AlertDialog.Builder#show 上的“android.view.WindowManager$BadTokenException”即使有保护措施的主要内容,如果未能解决你的问题,请参考以下文章

android 怎么使对话框(AlertDialog.Builder)自动消失

Dialog源码分析

如何关闭 AlertDialog.Builder?

android AlertDialog.Builder.setView(v) 点击v里面一个按钮怎么让对话框消失。这个问题你怎么解决的

转载android AlertDialog

自定义AlertDialog