美文网首页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