美文网首页android 技术知识
解决android中出现的“android.view.Windo

解决android中出现的“android.view.Windo

作者: 追梦小乐 | 来源:发表于2017-06-28 16:34 被阅读58次
image.png

Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@2c888438 is not valid; is your activity running?
按照字面上意思是:你的activity活动已经销毁了,但是你的Dialog之类的window还在运行,因为这些window的运行需要依附在activity活动上

看log定位错误信息

image.png

很明显就是在show Dialog的时候报错了

接着查看一下Dialog的代码

public abstract class BaseAlertDialog extends AlertDialog implements View.OnClickListener {

   protected View.OnClickListener mClickListener;
   protected View.OnClickListener mLeftListener;
   protected View.OnClickListener mRightListener;
   protected Object mDialogTitle;
   protected Object mDialogContent;
   protected Object mSingleBtn;
   protected Object mComplexLeftBtn;
   protected Object mComplexRightBtn;

   public BaseAlertDialog(@NonNull Context context) {
       super(context, R.style.style_dialog);
   }

   /**
    * 设置布局资源ID
    * @return 布局资源ID
    */
   protected abstract int getLayoutResId();

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setCanceledOnTouchOutside(false);
       if (getLayoutResId() != 0) {
           setContentView(getLayoutResId());
           initView();
       }
   }

   /**
    * 初始化控件
    */
   protected abstract void initView();

   /**
    * 设置弹框标题
    * @param dialogTitle 弹框标题内容
    */
   public void setDialogTitle(Object dialogTitle) {
       this.mDialogTitle = dialogTitle;
   }

   /**
    * 设置弹框内容
    * @param dialogContent 弹框显示内容
    */
   public void setDialogContent(Object dialogContent) {
       this.mDialogContent = dialogContent;
   }

   public void setDialogContent(Object dialogContent,Object dialogContentStr) {
       this.mDialogContent = dialogContent;
   }

   @SuppressWarnings("unchecked")
   protected  <T extends View> T xFindViewById(int resourceId) {
       return (T) findViewById(resourceId);
   }

   @Override
   public boolean onKeyDown(int keyCode, KeyEvent event) {
       return keyCode == KeyEvent.KEYCODE_BACK || super.onKeyDown(keyCode, event);
   }

   @Override
   public void onClick(View view) {

   }
}

这里只是最基本的Dialog的基类,也没什么好说,接着看它的实现类

public class SingleBtnDialog extends BaseAlertDialog {

    public SingleBtnDialog(@NonNull Context context) {
        super(context);
    }

    /**
     * 设置按钮监听
     * @param listener 自定义监听
     */
    public void setOnClickListener(View.OnClickListener listener) {
        this.mClickListener = listener;
    }

    /**
     * 设置按钮内容
     * @param singleBtnObj 按钮显示内容
     */
    public void setSingleBtn(Object singleBtnObj) {
        this.mSingleBtn = singleBtnObj;
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.dialog_single_btn_layout;
    }

    @Override
    protected void initView() {
        TextView tvDialogTitle = xFindViewById(R.id.tv_dialog_content_title);
        ViewUtils.loadContent(tvDialogTitle, mDialogTitle);
        TextView tvDialogContent = xFindViewById(R.id.tv_dialog_content);
        ViewUtils.loadContent(tvDialogContent, mDialogContent);

        Button btnSingleOption = xFindViewById(R.id.btn_dialog_single_option);
        ViewUtils.loadContent(btnSingleOption, mSingleBtn);
        if (mClickListener != null) {
            btnSingleOption.setOnClickListener(mClickListener);
        } else {
            btnSingleOption.setOnClickListener(this);
        }
    }

    @Override
    public void onClick(View view) {
        this.cancel();
        this.dismiss();
    }
}

好像也看出有什么问题,那接下来就看它的调用

 public void showFinishActSingleBtnDialog(String content){
        if (singleBtnDialog == null){
            singleBtnDialog = new SingleBtnDialog(getActivity());
        }
        singleBtnDialog.setDialogContent(content);
        singleBtnDialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().finish();
            }
        });
        singleBtnDialog.show();
    }

    public void showFinishActSingleBtnDialog(int contentId){
        showFinishActSingleBtnDialog(getString(contentId));
    }

可以看出没有对activity是否还在运行做判断,修改如下:

 public void showFinishActSingleBtnDialog(String content){
        if (singleBtnDialog != null && singleBtnDialog.isShowing()){
            singleBtnDialog.dismiss();
            singleBtnDialog = null;
        }
        if (!getActivity().isFinishing()){
            final SingleBtnDialog singleBtnDialog = new SingleBtnDialog(getActivity());
            singleBtnDialog.setDialogContent(content);
            singleBtnDialog.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    getActivity().finish();
                }
            });
            singleBtnDialog.show();
        }

//        if (singleBtnDialog == null){
//            singleBtnDialog = new SingleBtnDialog(getActivity());
//        }
//        singleBtnDialog.setDialogContent(content);
//        singleBtnDialog.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                getActivity().finish();
//            }
//        });
//        singleBtnDialog.show();
    }

对activity是否在运行判断了一下,然后重新赋值就可以了

相关文章

网友评论

    本文标题:解决android中出现的“android.view.Windo

    本文链接:https://www.haomeiwen.com/subject/zkvucxtx.html