Android :我的奇怪BUG:WindowManager$BadTokenException
来源:互联网 发布:医学必备数据分析软件 编辑:程序博客网 时间:2024/06/02 13:51
- BUG出现场景:在二次弹出自定义对话框的时候抛出的异常
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@406ab4c8 is not valid; is your activity running?at android.view.ViewRoot.setView(ViewRoot.java:532)at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:200)at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:114)at android.view.Window$LocalWindowManager.addView(Window.java:424)at android.app.Dialog.show(Dialog.java:241)at android.app.AlertDialog$Builder.show(AlertDialog.java:802)
- 这个BUG网上的解决方案真是特别的多。要么是使用
getParent()
代替当前的Activity.this
; - 要么是在对话框弹出之前,进行
activity.this.isFinish(
)判断一下。但是很不幸,这两种解决方式都不能解决我的问题。- 先说第一种,使用
Activity.this.getParent()
。很不幸,这个方法的返回值只有在当前Activity
继承自android.app.ActivityGroup
才不返回null
.所以,对我无效。 - 再说第二种,看起来有道理的样子,但是我加上这个判断之后,错误依然存在,没有解决我的问题。
- 先说第一种,使用
- 然后我找了很久,一直没有找到我的问题的解决方式。后来无意中发现了问题出在了我的单例模式的工具类上面。
- 我将弹出自定义对话框的代码放进了一个单例的工具类中,以为很牛逼,很高大上。但是问题就出现在单例模式上。单例获取的对象永远是唯一对象,且
final
过,也就是说,App不结束,这个对象是不会被回收的。也不能手动置空。但是Activity
是很脆弱的,一下就挂了。所以,正确的做法就是,在Activity
销毁的时候,销毁这个对话框的工具类对象,这样就OK了。【实际上不去在销毁Activity的时候,手动置空该工具类对象也是OK的,应该是Activity在销毁的时候,会干掉自己的成员变量的吧,不清楚….】
正确调用方式:
- 我将弹出自定义对话框的代码放进了一个单例的工具类中,以为很牛逼,很高大上。但是问题就出现在单例模式上。单例获取的对象永远是唯一对象,且
public class SecondActivity extends Activity { private Context context; private List<Bean> data; private MydialogUtils mydialogUtils; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second_layout); context = this; mydialogUtils = new MydialogUtils(); data = new ArrayList<Bean>(); data.add(new Bean("local system db", false)); data.add(new Bean("local system file", true)); data.add(new Bean("local private db", false)); data.add(new Bean("local private file", true)); findViewById(R.id.button1).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mydialogUtils.showMyDialog(context, data); } }); } @Override protected void onDestroy() { mydialogUtils.destoryMydialog();// mydialogUtils = null; super.onDestroy(); }}
mydialogUtils
一定要是一个普通的对象,不要是一个单例对象,或者一个死不掉的对象。!!!!
对话框的工具类:
public class MydialogUtils { public static final MydialogUtils UTILS = new MydialogUtils(); private View dialogView; private AlertDialog mDialog; public static MydialogUtils getInstance() { return UTILS; } public void showMyDialog(final Context context, final List<Bean> data) { Log.e("aaa", "aaa-->openMydialog"); AlertDialog.Builder builder = new AlertDialog.Builder(context); if (dialogView == null) { dialogView = View.inflate(context, R.layout.dialog_layout, null); } builder.setView(dialogView); final TextView tvTitle = (TextView) dialogView .findViewById(R.id.tvTitle); final TextView tv0 = (TextView) dialogView.findViewById(R.id.tv0); final TextView tv1 = (TextView) dialogView.findViewById(R.id.tv1); final TextView tv2 = (TextView) dialogView.findViewById(R.id.tv2); final TextView tv3 = (TextView) dialogView.findViewById(R.id.tv3); final CheckBox cb0 = (CheckBox) dialogView.findViewById(R.id.cb0); final CheckBox cb1 = (CheckBox) dialogView.findViewById(R.id.cb1); final CheckBox cb2 = (CheckBox) dialogView.findViewById(R.id.cb2); final CheckBox cb3 = (CheckBox) dialogView.findViewById(R.id.cb3); final View layout0 = dialogView.findViewById(R.id.tv0Layout); final View layout1 = dialogView.findViewById(R.id.tv1Layout); final View layout2 = dialogView.findViewById(R.id.tv2Layout); final View layout3 = dialogView.findViewById(R.id.tv3Layout); tv0.setText(data.get(0).getStr()); tv1.setText(data.get(1).getStr()); tv2.setText(data.get(2).getStr()); tv3.setText(data.get(3).getStr()); cb0.setChecked(data.get(0).isCheck()); cb1.setChecked(data.get(1).isCheck()); cb2.setChecked(data.get(2).isCheck()); cb3.setChecked(data.get(3).isCheck()); layout0.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bean bean = data.get(0); bean.setCheck(!bean.isCheck()); cb0.setChecked(bean.isCheck()); } }); layout1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bean bean = data.get(1); bean.setCheck(!bean.isCheck()); cb1.setChecked(bean.isCheck()); } }); layout2.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bean bean = data.get(2); bean.setCheck(!bean.isCheck()); cb2.setChecked(bean.isCheck()); } }); layout3.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Bean bean = data.get(3); bean.setCheck(!bean.isCheck()); cb3.setChecked(bean.isCheck()); } }); final TextView tvCancel = (TextView) dialogView .findViewById(R.id.tvCancel); final TextView tvOK = (TextView) dialogView.findViewById(R.id.tvOK); tvCancel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { initData(data); closeMyDialog(); } }); tvOK.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.v("aaa", "#####start"); for (Bean bean : data) { Log.e("aaa", "" + bean); } Log.v("aaa", "#####start"); // Log.e("aaa", "all-->" + data); closeMyDialog(); } }); if (mDialog == null) mDialog = builder.create();// 不能create多次!!! mDialog.show(); } public void closeMyDialog() { if (mDialog != null && mDialog.isShowing()) mDialog.dismiss(); } private void initData(List<Bean> data) { if (data != null) { data.clear(); data.add(new Bean("local system db", false)); data.add(new Bean("local system file", true)); data.add(new Bean("local private db", false)); data.add(new Bean("local private file", true)); } } public void destoryMydialog() { if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } mDialog = null; }}
工具类有点麻烦,不用去看,就是不要做成单例就可以了。
0 0
- Android :我的奇怪BUG:WindowManager$BadTokenException
- Android :我的奇怪BUG:WindowManager$BadTokenException
- Android :BUG:WindowManager$BadTokenException
- Android :子Activity 使用dialog 引发的BUG--android.view.WindowManager$BadTokenException: Unable to add wind
- Android贴吧系统学习-----悬浮布局出现的bug--android.view.WindowManager$BadTokenException:
- android中WindowManager BadTokenException的处理小结
- 解决常见的android.view.WindowManager$BadTokenException
- Android WindowManager$BadTokenException异常
- android.view.WindowManager$BadTokenException
- Android WindowManager$BadTokenException异常
- android.view.WindowManager$BadTokenException
- Android WindowManager$BadTokenException异常
- Android WindowManager$BadTokenException 处理
- Android WindowManager$BadTokenException错误
- android.view.WindowManager$BadTokenException
- android.view.WindowManager$BadTokenException
- 解决Android WindowManager$BadTokenException异常
- 解决异常Android WindowManager$BadTokenException
- Extjs4 的ComboBox select 事件(event)的例子(代码)
- onclick onclientclick postback 机制
- ldp hello报文接收的处理流程
- 随笔
- Android :我的奇怪BUG:WindowManager$BadTokenException
- Android :我的奇怪BUG:WindowManager$BadTokenException
- INSERT小记(insert into select和not in,values括号里不能放select)
- 对大二上学期的总结
- Linux基础知识第二期《目录处理命令》
- JavaScript保存CSV格式数据到客户端本地
- 如何删除在XenCenter里无法删除的SR存储
- php获取完整的地址栏
- Unity3D学习之Camera
- navicate 破解