WebView.loadData与loadUrl差异:loadData加载本地HTML为何空白?
问题
用WebView的loadUrl加载assets目录下的phonetest.html时显示完全正常:
webView.loadUrl("file:///android_asset/phonetest.html");
但把同一文件内容读取成String后,用loadData加载时WebView直接空白,TextView却能准确显示读取到的HTML内容,相关代码:
try( InputStream fis = getAssets().open("phonetest.html" ) ) { String text = "", line; BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); if (fis != null) { while ((line = reader.readLine()) != null) { text += line + "\n"; } webView.loadData(text, "text/html; charset=UTF-8", null); txtView.setText(text); } } catch( IOException e ) { throw new RuntimeException(e); }
开发环境:Android Studio Hedgehog | 2023.1.1,Build #AI-231.9392.1.2311.11076708,运行时版本:17.0.7+0-17.0.7b1000.6-10550314 amd64,系统:Linux 5.4.0-169-generic
原因
loadData的编码要求:loadData必须传入URL编码后的HTML字符串,直接传原始字符串会因为特殊字符(比如&、#、空格等)导致WebView解析失败;而loadUrl是直接加载本地文件,WebView会自动处理编码和内容解析。- 本地资源依赖(若存在):如果
phonetest.html里引用了assets中的图片、CSS或JS,loadData无法识别这些资源的路径,会导致页面加载异常甚至空白;loadUrl则会以assets目录为基础路径,自动找到这些资源。 - 字符串拼接的潜在问题:用
text += line的方式拼接字符串效率低,还可能在极端情况下出现编码截断,虽不会直接导致空白,但会叠加其他问题引发异常。
解决办法
方法1:用loadDataWithBaseURL替换loadData(推荐)
这个方法不需要手动编码,还能指定基础URL,让WebView正确识别HTML里引用的本地资源:
try( InputStream fis = getAssets().open("phonetest.html" ) ) { StringBuilder sb = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(fis, "UTF-8")); String line; while ((line = reader.readLine()) != null) { sb.append(line).append("\n"); } String htmlContent = sb.toString(); // 传入assets的基础路径,保证本地资源能被加载 webView.loadDataWithBaseURL("file:///android_asset/", htmlContent, "text/html", "UTF-8", null); txtView.setText(htmlContent); } catch( IOException e ) { throw new RuntimeException(e); }
方法2:对HTML字符串URL编码后用loadData
如果一定要用loadData,需要先把HTML内容做URL编码:
try( InputStream fis = getAssets().open("phonetest.html" ) ) { StringBuilder sb = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(fis, "UTF-8")); String line; while ((line = reader.readLine()) != null) { sb.append(line).append("\n"); } String htmlContent = sb.toString(); // 对HTML内容进行URL编码 String encodedHtml = URLEncoder.encode(htmlContent, "UTF-8"); webView.loadData(encodedHtml, "text/html; charset=UTF-8", "UTF-8"); txtView.setText(htmlContent); } catch( IOException | UnsupportedEncodingException e ) { throw new RuntimeException(e); }
内容的提问来源于stack exchange,提问作者hennep
相关产品推荐
相关产品推荐

