Dialog throwing "Unable to add window — token null

2018-12-31 12:58发布

My Activity is trying to create an AlertDialog which requires a Context as a parameter. This works as expected if I use:

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

However, I am leery of using "this" as a context due to the potential for memory leaks when Activity is destroyed and recreated even during something simple like a screen rotation. From a related post on the Android developer's blog:

There are two easy ways to avoid context-related memory leaks. The most obvious one is to avoid escaping the context outside of its own scope. The example above showed the case of a static reference but inner classes and their implicit reference to the outer class can be equally dangerous. The second solution is to use the Application context. This context will live as long as your application is alive and does not depend on the activities life cycle. If you plan on keeping long-lived objects that need a context, remember the application object. You can obtain it easily by calling Context.getApplicationContext() or Activity.getApplication().

But for the AlertDialog() neither getApplicationContext() or getApplication() is acceptable as a Context, as it throws the exception:

"Unable to add window — token null is not for an application”

per references: 1, 2, 3, etc.

So, should this really be considered a "bug", since we are officially advised to use Activity.getApplication() and yet it doesn't function as advertised?

Jim

24条回答
墨雨无痕
2楼-- · 2018-12-31 13:13

***** kotlin version *****

You should pass this@YourActivity instead of applicationContext or baseContext

查看更多
低头抚发
3楼-- · 2018-12-31 13:14

For future readers, this should help:

public void show() {
    if(mContext instanceof Activity) {
        Activity activity = (Activity) mContext;
        if (!activity.isFinishing() && !activity.isDestroyed()) {
            dialog.show();
        }
    }
}
查看更多
弹指情弦暗扣
4楼-- · 2018-12-31 13:14

Or another possibility is to create Dialog as follow:

final Dialog dialog = new Dialog(new ContextThemeWrapper(
            this, R.style.MyThemeDialog));
查看更多
永恒的永恒
5楼-- · 2018-12-31 13:16

adding

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

and

"android.permission.SYSTEM_ALERT_WINDOW"/> in manifest

It works for me now. After even close and open the application, gave me the error at that time.

查看更多
荒废的爱情
6楼-- · 2018-12-31 13:16

Try getParent() at the argument place of context like new AlertDialog.Builder(getParent()); Hope it will work, it worked for me.

查看更多
流年柔荑漫光年
7楼-- · 2018-12-31 13:19

I had to send my context through a constructor on a custom adapter displayed in a fragment and had this issue with getApplicationContext(). I solved it with:

this.getActivity().getWindow().getContext() in the fragments' onCreate callback.

查看更多
登录 后发表回答