Android Google Maps叠加Dialog后二次打开拖拽缩放卡顿问题求解
问题产生原因
卡顿的核心诱因来自你为Dialog窗口设置的两个特殊WindowManager标记:
FLAG_NOT_TOUCH_MODAL:允许窗口外的触摸事件分发到下层窗口FLAG_WATCH_OUTSIDE_TOUCH:让窗口持续接收窗口外区域的触摸事件回调
这两个标记会导致每次Dialog销毁后,系统输入事件分发器残留无效的窗口路由判断逻辑,每打开关闭一次Dialog就多一层冗余的事件校验步骤,进而导致地图接收触摸事件的延迟大幅升高,同时地图渲染线程被不必要的事件调度占用,出现掉帧卡顿。
另外你每次调用showDialog都会创建全新的Dialog实例,重复创建销毁窗口会放大上述标记带来的副作用。
解决方案
方案1:移除不必要的窗口标记(最优)
从你贴的代码来看,Dialog已经设置了setCancelable(false),没有特殊交互需求的话直接删除两行window.setFlags代码即可,修改后的showCommonDialog方法如下:
public Dialog showCommonDialog(Context context) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("test dialog"); builder.setMessage("test dialog"); builder.setCancelable(false); builder.setPositiveButton("dismiss", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { dialogInterface.dismiss(); } }); AlertDialog dialog = builder.create(); Window window = dialog.getWindow(); WindowManager.LayoutParams lp = window.getAttributes(); lp.width = WindowManager.LayoutParams.WRAP_CONTENT; lp.height = WindowManager.LayoutParams.WRAP_CONTENT; WindowManager m = window.getWindowManager(); Display d = m.getDefaultDisplay(); lp.width = (int) (d.getWidth() * 0.95); // 删除以下两行冗余的Flag设置 // window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, // WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL); // window.setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, // WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH); dialog.show(); return dialog; }
方案2:复用Dialog实例(适合必须保留上述Flag的业务场景)
如果业务确实需要用到这两个窗口标记,就不要每次触发弹窗都新建Dialog实例,改为全局复用同一个Dialog,避免重复创建窗口带来的属性叠加问题:
// 把Dialog改为全局成员变量 private Dialog commonDialog; private void showDialog() { if (commonDialog == null) { commonDialog = showCommonDialog(this); } else { commonDialog.show(); } }
同时可以在Dialog关闭后主动调用mapFragment.onResume()触发地图状态刷新,进一步降低卡顿概率。
内容的提问来源于stack exchange,提问作者OYBCBC
相关产品推荐
相关产品推荐

