安卓出现“无法添加窗口--令牌null不是应用程序”的异常

134

当我尝试打开对话框时,我遇到了以下的安卓异常。请问有人能帮我理解发生了什么,以及如何解决这个问题吗?

android.view.WindowManager$BadTokenException: 
  Unable to add window -- token null is not for an application
    at android.view.ViewRoot.setView(ViewRoot.java:509)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
    at android.app.Dialog.show(Dialog.java:241)

8
没有贴上一些代码,我们怎么知道呢? - Falmarri
1
请参考此答案,发布此答案链接的主要原因是在评论中有很好的讨论,描述了为什么会出现这个问题以及处理它的最佳方法是什么https://dev59.com/Rm025IYBdhLWcg3wyZIn#7229248。 - dharmendra
如果您使用Service,请阅读https://dev59.com/vX_aa4cB1Zd3GeqP3XIQ。 - CoolMind
12个回答

422

我猜想 - 你是想要在应用上下文中创建一个对话框?类似于这样:

new Dialog(getApplicationContext());

这是错误的。您需要使用Activity上下文。

您需要尝试像这样:

new Dialog(YourActivity.this);

1
谢谢。但是我没有使用 new Dialog(getApplicationContext()); 我只使用 'new AlertDialog.Builder(mContext);',其中 mContext 是一个活动的引用。 - michael
10
mContext应该是MyActivity.this。 - Luis
10
创建自定义对话框的Android文档(http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog)存在错误。Context mContext = getApplicationContext(); Dialog dialog = new Dialog(mContext);您提供的修复方法是: Dialog dialog = new Dialog(this);这个方法可行!谢谢。 - bnieland
1
http://developer.android.com/guide/topics/ui/dialogs.html 已经修复(一段时间以来)。只是为了参考而指出。模式也得到了改进。 :) - Martin Marconcini
2
使用 getActivity() @SagarDevanga - Pratik Butani
显示剩余4条评论

34

您可以继续使用getApplicationContext(),但在使用之前,您应该添加此标志:dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT),这样就不会显示错误。

还要记得添加权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

是的,这很简单。别忘了添加权限,我刚刚编辑过了。 - codezjx
3
无法在RecyclerAdapter中使用getActivity()方法。 - Martin Erlic
太棒了 :) - Syed Hamza Hassan
你如何添加标志? - Conner Dassen

13

在我的情况下,我试图像这样创建我的对话框:

new Dialog(getApplicationContext());

所以我不得不改变:

new Dialog(this);

对我来说它很正常 ;)


1
你的答案是正确的,但只能在活动范围内使用。如果你在内部范围内,你必须使用 MyActivity.class 代替 this,因为 this 引用了另一个对象。 - Shahar
1
此外,this 将确保您的 Dialog 继承您的主题。 - TheRealChx101

12

尝试将getParent()放在context的参数位置,例如:new AlertDialog.Builder(getParent()); 希望它能够正常工作,对我来说起作用了。


为什么要使用getParent()?这是什么意思? - José Castro
2
当您在另一个不扩展Activity类的类中显示任何对话框时,您可能无法获取扩展Activity类的上下文。因此,为了在您尝试显示对话框但不扩展Activity的类内部获取上下文,您可以使用getParent()方法,该方法返回您所需的上级Activity的上下文。 - Priyank Joshi
1
谢谢@PriyankJoshi,你救了我的一天,它也解决了“Android无法添加窗口无效;您的活动正在运行吗?”的奇怪异常。 - Eslam Yousef Mohammed
我该如何使用getParent()方法? - vinidog
谢谢!在我的情况下它起作用了。我之前调用的是 this.parent.getActivity().getApplicationContext(),但是 this.parent.getActivity() 就解决了问题。 - ace_ventura

3
我猜你是想使用Dialog创建对话框。
 getApplicationContext()
 mContext which is passed by activity.

如果您要在非活动类中显示对话框,则需要将活动作为参数传递。

Activity activity=YourActivity.this;

现在它将会工作得很好。如果您发现任何问题,请让我知道。

2

你好,如果你正在使用适配器,可能会有一些问题。
当你在适配器中使用任何对话框时,需要知道的是getContext()、context或activity有时不起作用。

这里是我使用的技巧: v.getRootView().getContext() 其中v是你正在引用的视图对象。
例如:


            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                new DatePickerDialog(v.getRootView().getContext(), date, myCalendar
                        .get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
                        myCalendar.get(Calendar.DAY_OF_MONTH)).show();
            }
        });  
If you are getting this problem because of alert dialog.
Refer [here][1] But it is same concept.


  [1]: https://dev59.com/mFjUa4cB1Zd3GeqPQEw9

谢谢!你救了我宝贵的时间!!(^_^) - Nice umang

2

我在上下文字段中尝试使用了以下内容:

this.getActivity().getParent()

我觉得这对我来说很好用。这是从一个扩展了“Fragment”类的类中得到的:

public class filtro extends Fragment{...

1
我通过在AndroidManifest.xml中添加以下用户权限来解决了此错误。
 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

同时,使用活动名称初始化警报对话框:

AlertDialog.Builder builder = new AlertDialog.Builder(YourActivity.this);

更多详情,请访问==> 如何在Android中创建警报对话框


1
我遇到了同样的异常。我解决这个问题的方法是将对话框实例作为参数传递到函数中,并使用它代替仅传递上下文并使用getContext()的方式。这个解决方案解决了我的问题,希望它能帮到你。

0

如果您正在尝试从片段中显示对话框,请使用“getActivity()”方法。

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接