You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebView加载HTML后绘制Bitmap首次正常后续为空问题咨询

问题原因
  • 引用对象不匹配:你在onPageFinished回调中调用createBitmapFromView时,方法内使用的是全局mView变量,而非当前回调返回的已加载完成的WebView实例。每次调用Print()方法都会新建一个WebView,但绘制时仍指向之前可能已经被回收/失效的旧View,导致后续生成Bitmap为空。
  • 回调时机错误:WebViewClient.onPageFinished仅代表WebView完成了资源加载流程,不代表页面内容已经完成渲染。后续调用时如果存在缓存,内核会快速回调onPageFinished,此时页面还没完成绘制,测量得到的宽高为0,生成的Bitmap自然为空。
  • 离屏渲染未开启:未添加到视图树的WebView默认不会开启离屏绘制,首次加载可能因为时序问题刚好渲染完成,后续复用内核资源时就会出现无法绘制到Canvas的情况。
修复方案

1. 修正绘制对象引用

修改createBitmapFromView方法,把要绘制的View作为参数传入,避免引用全局的旧View,同时增加宽高合法性判断:

public Bitmap createBitmapFromView(View view) {
    view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    if (view.getMeasuredWidth() <= 0 || view.getMeasuredHeight() <= 0) {
        return null;
    }
    Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
            view.getMeasuredHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bitmap);
    view.draw(c);
    return bitmap;
}

2. 修正WebView配置和回调逻辑

开启离屏渲染,禁用缓存避免历史内容干扰,同时调整等待时机确保渲染完成:

public void Print() {
    WebView mWebView = new WebView(activity);
    // 开启离屏渲染,允许未挂载到视图树的WebView绘制内容
    mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    mWebView.setInitialScale(400);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.setVerticalScrollBarEnabled(false);
    mWebView.getSettings().setDefaultTextEncodingName("utf-8");
    mWebView.getSettings().setUseWideViewPort(true);
    // 禁用缓存避免历史内容干扰
    mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
    mWebView.addJavascriptInterface(new JavaScriptInterface(), "HTMLOUT");
    mWebView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            // 等待渲染完成后再执行绘制
            view.postDelayed(() -> {
                Bitmap myBitmap = createBitmapFromView(view);
                if (myBitmap != null) {
                    print(myBitmap);
                }
                // 用完销毁WebView避免内存泄漏和缓存干扰
                view.destroy();
            }, 100);
        }
    });
    mWebView.loadData(mHtmlString, "text/html; charset=UTF-8", null);
}

3. 兜底处理

如果延迟后仍然偶现空Bitmap,可以在createBitmapFromView返回空时重试1-2次,最多重试3次避免死循环。

内容的提问来源于stack exchange,提问作者erkan demir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 22:48:03