最近遇到一个Android12版本View.post()获取不到宽高值的问题。

这个问题出在创建Bitmap的时候。

下面是一段生成页面图片的代码,主要是将一个布局生成为一个图片内容Bitmap。

报错代码

            final View waterMark = CameraPhoto.getWaterMark(activity, tempPath, waterMarkBean);
            if (waterMark != null) {
                waterMark.post(new Runnable() {
                    @Override
                    public void run() {
                        CameraPhoto.saveToTemp(CameraPhoto.getViewBitmap(waterMark));
                        CameraPhoto.removeTempletView(activity, waterMark);
                        threadToSave();
                    }
                });
            }
    /**
     * 截取view内容,生成图片
     *
     * @param view 容器控件
     * @return 图片bitmap
     */
    public static Bitmap getViewBitmap(View view) {
        try {
            Bitmap bitmap;
            // 创建相应大小的bitmap
            bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            final Canvas canvas = new Canvas(bitmap);
            //绘制viewGroup内容
            view.draw(canvas);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

报错原因

上面代码在执行到

Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight()

时,由于view.getMeasuredWidth()view.getMeasuredHeight()值为0,导致crash。

得到如下报错:

java.lang.IllegalArgumentException: width and height must be > 0

一般来说,在View.post()方法中获取宽高是能获取到的。

                view.post(new Runnable() {
                    @Override
                    public void run() {
                        //这里获取布局宽高
                    }
                });

但是,在Android12系统中,view.post方法确实获取不到宽高。

具体原因(源码)待分析。

解决方案

根据经验,我猜测刚inflate出来的view可能没有被加载到屏幕。

为了解决这个问题,我尝试使用view.postDelayed方法,延时100毫秒获取宽高。

                waterMark.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //这里获取布局宽高
                    }
                }, 100);

亲测有效,问题得到解决。