面向对象程序语言——各施其职-单一职责!

来源:互联网 发布:前程无忧有限公司 java 编辑:程序博客网 时间:2024/06/05 11:08

今天测试给提交了一个bug,

log显示android.view.WindowManager$BadTokenException: Unable to add window;

仔细分析上面的那句Unable to add window是说一个AlertDialog无法添加个window;

我们知道创建一个dialog,最常用的一个方法是AlertDialog.Builder(Context context),而这里的

context说白了就是一个活动,为什么会发生上面的情况呢?

因为对于dialog来说,他只能在创建它的activity上显示,在此例中,就是因为当系统想去把dialog

添加到window时,其实创建dialog的activity已经销毁了,所以系统就会很含蓄的说Unable to add window;

其实它很想说嘿傻瓜,手机屏都没了,怎么显示呀!

这只是会发生这种情况的一种原因!

在我所遇到的问题还和handler有关,handler负责其它线程来设置UI线程的工作,更具体的是handler其实是

负责它所在activity的UI的更新,它没有权力更改其它activity的UI!

好,下面看看我的具体例子:

有三个acitivity

ParentActivity——父类

Child01Acitivity extends ParentActivity——子类1

Child02Acitivity extends ParentActivity——子类2

CustomReceiver  extends BroadcastReceiver——自定义BroadcastReceiver

public class ParentActivity extends Activity{

public staticCustomReceiver mRecerver;

public Handler mHandler;

Alertdialog mAlertdialog;

mHandler在这初始化;

}

问题发生的就是这样的巧妙:

Child01Acitivity oncreate中:

mRecerver=new CustomReceiver (mHandler);

在Child02Acitivityoncreate中:

mRecerver=new CustomReceiver (mHandler);

其实代码没有任何问题;

但是当我们这样来用软件的时候就有问题了;

1.打开Child01Acitivity

2.从Child01Acitivity跳转到Child02Acitivity;

3.在Child02Acitivity中让mAlertdialog正常显示;

4.Child02Acitivity中按返回键到Child01Acitivity

5.Child01Acitivity中注册mRecerver并通过它去尝试打开mAlertdialog----------这里就发生了android.view.WindowManager$BadTokenException: Unable to add window;

 我们来分析一下1.中新建了mRecerver,此时mHandler属于Child01Acitivity;

2.中新建了mRecerver,把在1.中的mRecerver覆盖了 此时mHandler,mAlertdialog属于Child02Acitivity;mRecerver也属于Child01Acitivity

3.中没有问题

4.中Child01Acitivity是不会执行oncreate方法的,所以mHandler,mAlertdialog还是属于Child02Acitivity,Child02Acitivity已经没有了

5.中当你拿着mRecerver去打开mAlertdialog时就报错了,因为这里你就是想让Child02Acitivity中的mHandler去打开Child02Acitivity中的mAlertdialog,怎么能行哟,

Child02Acitivity已经 没有了!

!!!


所以面向对象,你要明白各施其职,该谁来做的事就必须谁来做,也许更能表现这一点的就是单一职责原则吧!

static好是好,但你一定要弄清!不然问题有了,你都不知道问题在哪里!


感谢我们伟大的娜娜!



原创粉丝点击