弓背霞明剑照霜,秋风走马出咸阳。这篇文章主要讲述AlertDialog 的context 不能是application的context相关的知识,希望能为你提供帮助。
昨天做了一个demo,静态注册的BroadcastrReceiver在onReceive方法里实现 alertdialog.
但是,健哥说我的这个会报错,但是为什么没报错很奇怪,我也很奇怪,今早一来我就研究了一下alertdialog的坑。
dialog 是类型同activity的应用窗口,都可以创建phonewindow实例。
看看dialog的构造函数:
Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) { // 忽略一些代码 mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); final Window w = new PhoneWindow(mContext); mWindow = w; w.setCallback(this); w.setOnWindowDismissedCallback(this); w.setWindowManager(mWindowManager, null, null); //就是这句话。 w.setGravity(Gravity.CENTER); mListenersHandler = new ListenersHandler(this); }
setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) 第二个参数,我们设为null了。(而在activity中,这个token被设为ActivityThread传过来的token。tockon呢是用来表示窗口的一个令牌,只有符合条件的token才能被WMS通过添加到应用上。)
在Dialog的show方法中,
public void show() {
// 忽略一些代码
mDecor = mWindow.getDecorView();
WindowManager.LayoutParams l = mWindow.getAttributes();
// 忽略一些代码
try {
mWindowManager.addView(mDecor, l);
//返回manager的时候,如果tockon不为空会调用getSystemService(),为空会报出异常。
mShowing = true; sendShowMessage(); } finally { } }
public Object getSystemService(@ServiceName @NonNull String name) { if (getBaseContext() == null) { throw new IllegalStateException( "System services not available to Activities before onCreate()"); }//因为一直传过来的context的tockenif (WINDOW_SERVICE.equals(name)) { return mWindowManager; } else if (SEARCH_SERVICE.equals(name)) { ensureSearchManager(); return mSearchManager; } return super.getSystemService(name); }
系统对TYPE_APPLICATION类型的窗口,要求必需是Activity的Token,不是的话系统会抛出BadTokenException异常。Dialog 是应用窗口类型,Token必须是Activity的Token。
【AlertDialog 的context 不能是application的context】
推荐阅读
- appium 键盘按键用法
- GWT JavaScript本机接口(JSNI)
- Win8电脑鼠标指针怎样换?Win8电脑鼠标指针更改办法
- Win8怎样查看电脑设置?Win8查看电脑设置的办法
- Win8电脑结束进程快捷键是啥?
- Win8关闭445端口的办法
- Win8注册表编辑器怎样打开?Win8打开注册表编辑器的办法
- Win8电脑如何设置静音快捷键?Win8电脑设置静音快捷键的办法
- Win8如何设置默认输入法?Win8输入法设置办法