后台弹窗-Dialog只显示了一层蒙灰,没有布局,DialogFragment无法点击交互

问题叙述

APP业务需求是,使用了一个后台服务监听后台推送通知,有些通知收到后就要弹窗展示给用户,并做相关操作,这样就出现了:

第一个问题

使用Dialog时,当切到后台执行弹窗后,再次将APP切换到前台后,弹窗的UI没有出现,页面上出现一层蒙灰,其下层页面点击事件正常;

第二个问题

使用的DialogFragment弹窗时,因为需求要做成只显示一个弹窗,要关闭已经展示的弹窗,显示新的弹窗,然而APP切到后台后,收到推送执行多次弹窗操作后,再次进入APP发现弹窗失去了焦点,点击时间响应不了;

第一个问题分析-Dialog异常

于是看了下log发现当应用在后台的时候,如果弹窗的DecorView没有写死宽高,在Android10上会出现不测量,不布局的现象;

解决第一个问题

因为是Dialog所以我可以获取到焦点变化监听,回到前台是我判断下是否有焦点,是否已经显示了Dialog,再决定是否发起重绘;

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        Window window = getWindow();
        if (hasFocus && window != null) {
            View decorView = window.getDecorView();
            if (decorView.getHeight() == 0 || decorView.getWidth() == 0) {
                decorView.requestLayout();
                Log.d("aster", "布局异常,重新布局");
            }
        }
    }

第二个问题分析-DialogFragment异常

根据以往经验对第一个问题,首先怀疑是弹窗正常,窗体焦点不明原因丢失导致的,但是真正等debug时,发现代码在后台弹出多个弹窗时,我的业务逻辑是要在弹出下一个弹窗时关闭上一个弹窗,这是DialogFragment出现了报错:

  IllegalStateException: Can not perform this action after onSaveInstanceState

解决第二个问题

这个问题就很好解决了
因为 onSaveInstanceState()方法是在该Activity即将被销毁前调用,来保存Activity数据的,如果在保存完状态后再给它添加 Fragment 或者 dismiss (DialogFragment类方法)就会出错。
Fragment的此种报错多见于使用commit()方法时的报错,将该方法使用commitAllowingStateLoss()替换即可。
DialogFragment的此种报错一般是在关闭时使用了dismiss()方法;将该方法使用dismissAllowingStateLoss()替换即可。
检查代码逻辑:

                      //这个confirmDialog 是一个DialogFragment,始终只显示一个弹窗
                        if (confirmDialog != null) {
                            confirmDialog.dismiss();
                        }
                        //关闭上一个后再重新显示一个弹窗
                        showPrescriptionFailDialog(prescription_fail_no);

替换关闭方法dismissAllowingStateLoss即可;
问题解决

跑了一下正常显示,问题解决

你可能感兴趣的:(后台弹窗-Dialog只显示了一层蒙灰,没有布局,DialogFragment无法点击交互)