WebView加载HTML后,如何无需忙等获取最终渲染高度?
解决方案
1. 通过JS监听页面完全渲染并同步最终高度
这是最可靠的方案,能精准捕获页面动态内容(图片、异步脚本、CSS重排)的加载完成状态:
- 在HTML加载完成后,通过
evaluateJavascript注入JS逻辑,监听所有资源加载及页面尺寸稳定:
webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 注入JS监听页面最终渲染完成 String js = "function checkHeight() {" + " var currentHeight = document.documentElement.scrollHeight;" + " var timer = setInterval(function() {" + " var newHeight = document.documentElement.scrollHeight;" + " if (newHeight === currentHeight) {" + " clearInterval(timer);" + " window.android.onPageRenderFinished(newHeight);" + " } else {" + " currentHeight = newHeight;" + " }" + " }, 100);" + "}" + "// 等待初始资源加载完成" + "window.onload = function() {" + " checkHeight();" + "};" + "// 监听所有图片加载(覆盖懒加载场景)" + "var imgs = document.getElementsByTagName('img');" + "for(var i=0; i<imgs.length; i++) {" + " if(imgs[i].complete) continue;" + " imgs[i].onload = function() {" + " checkHeight();" + " };" + "}"; view.evaluateJavascript(js, null); } }); // 定义JS交互接口,接收最终高度 webView.addJavascriptInterface(new Object() { @JavascriptInterface public void onPageRenderFinished(int height) { // 此时获取的height为最终渲染高度,可安全执行测量和截图 webView.measure(View.MeasureSpec.makeMeasureSpec(webView.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)); // 后续位图转换逻辑 } }, "android");
- 逻辑说明:
window.onload确保DOM及初始资源加载完成;- 遍历监听所有图片的
onload事件,覆盖懒加载图片的场景; - 定时器轮询页面滚动高度,直到连续两次高度一致,确认尺寸稳定;
- 通过JS接口将最终高度传递给Native,避免忙等和测量偏差。
2. 结合ViewTreeObserver监听布局变化
若不想依赖JS,可通过Native端布局监听判断高度稳定:
ViewTreeObserver observer = webView.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { private int lastHeight = 0; private int stableCount = 0; @Override public void onGlobalLayout() { int currentHeight = webView.getMeasuredHeight(); if (currentHeight == lastHeight) { stableCount++; if (stableCount >= 2) { // 连续两次布局高度一致,确认稳定 webView.getViewTreeObserver().removeOnGlobalLayoutListener(this); // 执行截图操作 } } else { lastHeight = currentHeight; stableCount = 0; } } });
- 注意:需及时移除监听避免内存泄漏,该方案对JS动态修改DOM的场景兼容性略逊于JS监听。
原有回调不可靠的原因
onPageCommitVisible:仅在页面内容开始可见时触发,此时资源可能仍在加载、DOM未完全渲染,导致测量高度为0或不准确;onPageFinished:仅代表DOM加载完成,图片、异步脚本、CSS动画等可能仍在执行,会导致页面高度后续变化,Android 9/10上触发更早是因为系统对WebView加载逻辑做了调整。
内容的提问来源于stack exchange,提问作者Ariczek
相关产品推荐
相关产品推荐

