Android Crash解决方案之android.view.WindowManager$BadTokenException
2016-07-05 10:27
507 查看
【崩溃堆栈】:
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:543)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:259)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:286)
at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
at bugrpt.test.CrashCase.showDialog(CrashCase.java:104)
at bugrpt.test.CrashCase.signalCrash(CrashCase.java:126)
at com.example.crash.MainActivity$9.onClick(MainActivity.java:231)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5045)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
【崩溃代码与现象】:
其中,mContext由getApplicationContext()得到。
【Bug分析】:
在分析该错误之前,我们先看下AlertDialog.Builder的函数原型,如下:
参数为Context类型,根据上面的代码,传入的也是Context类型参数,貌似没有什么问题。其实不然,getApplicationContext()获得的context为整个应用的上下文,而对于AlertDialog来说,是需要依赖一个View,而View是对应于Activity的。所以,一般传入应该为Acitivity.this。
另外,下面几种情况也会引起该异常,分别如下:
A、在activity的oncreate方法中使用popupwindow出现以下错误:
异常:
android.view.WindowManager$BadTokenException: Unable to add window --token null is not valid; is your activity running?
错误代码如下:
pop = new PopupWindow(pop_view,320,250);
pop.showAtLocation(parent, Gravity.TOP,0, 0);
解决方法:
在控件渲染未完成前,就调用了pop.showAtLocation(parent, Gravity.TOP,0, 0)方法。
B、dialog.show()引起的android.view.WindowManager$BadTokenException错误:
异常:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@427b7270 is not valid; is your activity running?
错误原因:
Dialog在show的时候必须要有一个activity作为窗口载体,但是承载Dialog的activity已经被销毁了,不存在了,所以报上面的异常。
【解决方案】
针对上面引起异常的不同情况,下面分别说明:
本案例异常的解决方案:
对AlertDialog来说,需要依赖一个View,而View是对应于Activity的。所以,一般传入应该为Acitivity.this,即Activity自身context。
其他案例:
A、对于未渲染完成,就调用了showAtLocation方法的解决方案:
1、移到事件中(比如一个button的click事件中);
2、移到子线程中;另起一线程,在线程中不断循环,直到判断控件是否渲染完毕(如长宽大于0),不推荐。。。
3、移到重写的控件(parent)中,在控件ondraw()完后生成pop。
4、或者采用有如下的方案,原理为:当activity获得焦点之后,activity是加载完毕的了。其中showPopupWindow(getApplicationContext())是自己定义的专门显示popupwindow的一个函数。
B、对于Dialog调用已经销毁的activity的解决方案:
在show之前加判断activity是否被销毁了,如下:
if(!isFinishing()){
dialog.show();
}
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:543)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:259)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:286)
at android.app.AlertDialog$Builder.show(AlertDialog.java:951)
at bugrpt.test.CrashCase.showDialog(CrashCase.java:104)
at bugrpt.test.CrashCase.signalCrash(CrashCase.java:126)
at com.example.crash.MainActivity$9.onClick(MainActivity.java:231)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5045)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
【崩溃代码与现象】:
其中,mContext由getApplicationContext()得到。
【Bug分析】:
在分析该错误之前,我们先看下AlertDialog.Builder的函数原型,如下:
参数为Context类型,根据上面的代码,传入的也是Context类型参数,貌似没有什么问题。其实不然,getApplicationContext()获得的context为整个应用的上下文,而对于AlertDialog来说,是需要依赖一个View,而View是对应于Activity的。所以,一般传入应该为Acitivity.this。
另外,下面几种情况也会引起该异常,分别如下:
A、在activity的oncreate方法中使用popupwindow出现以下错误:
异常:
android.view.WindowManager$BadTokenException: Unable to add window --token null is not valid; is your activity running?
错误代码如下:
pop = new PopupWindow(pop_view,320,250);
pop.showAtLocation(parent, Gravity.TOP,0, 0);
解决方法:
在控件渲染未完成前,就调用了pop.showAtLocation(parent, Gravity.TOP,0, 0)方法。
B、dialog.show()引起的android.view.WindowManager$BadTokenException错误:
异常:
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@427b7270 is not valid; is your activity running?
错误原因:
Dialog在show的时候必须要有一个activity作为窗口载体,但是承载Dialog的activity已经被销毁了,不存在了,所以报上面的异常。
【解决方案】
针对上面引起异常的不同情况,下面分别说明:
本案例异常的解决方案:
对AlertDialog来说,需要依赖一个View,而View是对应于Activity的。所以,一般传入应该为Acitivity.this,即Activity自身context。
其他案例:
A、对于未渲染完成,就调用了showAtLocation方法的解决方案:
1、移到事件中(比如一个button的click事件中);
2、移到子线程中;另起一线程,在线程中不断循环,直到判断控件是否渲染完毕(如长宽大于0),不推荐。。。
3、移到重写的控件(parent)中,在控件ondraw()完后生成pop。
4、或者采用有如下的方案,原理为:当activity获得焦点之后,activity是加载完毕的了。其中showPopupWindow(getApplicationContext())是自己定义的专门显示popupwindow的一个函数。
B、对于Dialog调用已经销毁的activity的解决方案:
在show之前加判断activity是否被销毁了,如下:
if(!isFinishing()){
dialog.show();
}
相关文章推荐
- Android 异常日志捕捉Crash
- 移动平台崩溃收集分析系统之 --crashlytics、友盟、bugly、网易云捕对比
- iOS Crash文件的解析(一)
- 中国互联网大会--------网易云捕助力产品打造高品质APP
- android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an appli
- 聊聊从iOS固件提取系统库符号
- Android快速批量多渠道包的“蛋生”
- 聊聊从iOS固件提取系统库符号
- Android自动化测试工具实现简述
- 高手谈Android NDK C++ RTTI 分析
- iOS崩溃堆栈信息的符号化解析
- Android NDK编译选项设置
- 【iOS系列】聊聊 "-ObjC" 的故事
- 网易云捕1.5版本已经上线,重磅功能来袭
- 不需要权限的获取蓝牙mac地址方法
- Android Crash解决方案之java.lang.UnsatisfiedLinkError
- A/art: art/runtime/mirror/art_method.cc:201] Failed to find Dex offset for PC offset 0x92419070(PC 0
- Android开发之如何处理APP意外崩溃问题
- 网易云捕:一款iOS平台下方便好用的崩溃收集统计系统
- Android菜鸟学步之启动模式