最近遇到一个问题,android端需要用webview加载一个html片段,网上各种搜索之后,实现了刚开始的功能,具体如下:
xml文件,很简单,一个webview:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
然后是代码中的使用:
webView = view.findViewById(R.id.webview);
String mycontent = "<p style="font-family: 微软雅黑; padding: 0px; margin-bottom: 1em; line-height: 2; color: rgb(43, 43, 43); text-indent: 2em; font-size: 16px;">4月29日,县商工局按照县委县政府关于防汛工作的总体安排部署,结合脱贫攻坚包扶村的实际情况,组织全局干部职工和村、组应急队伍开展了一次模拟防汛抢险应急演练文明实践活动。</p><p style="text-align: center; font-family: 微软雅黑; padding: 0px; margin-bottom: 0px; line-height: 18px; color: rgb(43, 43, 43); font-size: 12px;"><img title="" alt="" src="http://gxj.baoji.gov.cn/images/image/201904/20190430181529_10083.jpg" width="680" height="382"></p><p style="font-family: 微软雅黑; padding: 0px; margin-bottom: 1em; line-height: 2; color: rgb(43, 43, 43); text-indent: 2em; font-size: 16px;">参加防汛抢险应急演练人员按照预案,实地演练了河水暴涨,使两岸村民生命财产受到严重危急时刻,干部群众团结一致、密切配合,服从指挥、各司其职,保证了防汛应急抢险工作有序开展。同时,对演练中存在的不足,进行了现场讲评。</p><p style="text-align: center; font-family: 微软雅黑; padding: 0px; margin-bottom: 0px; line-height: 18px; color: rgb(43, 43, 43); font-size: 12px;"><img title="" alt="" src="http://gxj.baoji.gov.cn/images/image/201904/20190430181552_39628.jpg" width="680" height="322"></p><p style="font-family: 微软雅黑; padding: 0px; margin-bottom: 1em; line-height: 2; color: rgb(43, 43, 43); text-indent: 2em; font-size: 16px;">这次活动活动本着“以人为本,生命至上”的宗旨,立足防大汛、抢大险,在汛情紧急的情况下,能够迅速、高效、有序地组织群众安全撤离危险区域。通过这次防汛应急演练文明实践活动,不仅提高了群众防灾避灾意识,也提高了干部群众在防汛抢险中快速反应的处置能力。</p><p style="text-align: center; font-family: 微软雅黑; padding: 0px; margin-bottom: 0px; line-height: 18px; color: rgb(43, 43, 43); font-size: 12px;"><img title="" alt="" src="http://gxj.baoji.gov.cn/images/image/201904/20190430181621_72449.jpg" width="680" height="322"></p>";
webView.getSettings().setDefaultTextEncodingName("utf-8");
webView.loadDataWithBaseURL(null, getNewContent(html), "text/html", "utf-8", null);
这里需要敲黑板划重点:
当我们要加载的html片段和上边代码中示例的一样,含有转义字符和css样式时,我们要使用webView.loadDataWithBaseURL这个方法,不能用webView.loadData,原因是loadData()中的html data中不能包含'#', '%', '\', '?'这四中特殊字符。
大家一定要注意,否则加载出来可能就是乱码。
到这里,webview加载html片段的功能已经实现。接下来就是“但是”了。
但是,又遇到了新的问题,后台那边在提交数据的时候,直接把图片转码成base64字节存到了数据库,并且是夹杂在html片段中。
所以,首先要将base64字节从字符串中分离出来,做法如下(我是把解析放到服务端):
找到字节的起始位置的字符串,一般都是一样的,我们是开始位置是“base64,”这个字符串,结束位置是一个转义字符“"”,这样我们就可以将字符串用“base64,”先分割,然后再解析,解析完成后将图片存储,然后用图片的路径重新组装原串中的<img>标签,代码如下:
public String parseContent(String content,String id) {
Pattern compile = Pattern.compile("base64,");//创建切割对象,将以"src="切割字符串
String[] split = compile.split(content);//执行切割,获得字符串数组
String parseResult = split[0].replace("data:image/png;", "");
List<String> imgPaths = new ArrayList<>();
List<Map<String,Object>> list = new ArrayList<>();//创建集合用来装最终的图片地址
if(split.length>0) {
for (int i=1;i<split.length;i++) {//对字符串数组遍历
String s1 = split[i];
if(!s1.contains("base64,") && s1.length()>100 && s1.indexOf(""")>=0) {//indexOf方法是寻找给定的字符"http"在字符串中的位置,并把该所在位置的索引值返回,如果找不到返回-1
String result = s1.substring(0,s1.indexOf("""));//substring方法用来截取字符串
generateImage(result,path+"/images/net"+id+i+".jpg");
imgPaths.add("http://172.29.31.52:8080/MyWeb/images/net"+id+i+".jpg");
parseResult = parseResult + imgPaths.get(i-1)+"";
parseResult = parseResult + s1.replace(result, "").replace("data:image/png;", "");
}
}
}
System.out.println("parseResult===="+parseResult);
return parseResult;
}
// base64 转成图片
public static boolean generateImage(String imgStr, String imgFilePath) {// 对字节数组字符串进行Base64解码并生成图片
if (imgStr == null) // 图像数据为空
return false;
System.out.println("path===="+imgFilePath);
File file = new File(imgFilePath);
final Base64 base64 = new Base64();
try {
// Base64解码
byte[] bytes = base64.decode(imgStr);
for (int i = 0; i < bytes.length; ++i) {
if (bytes[i] < 0) {// 调整异常数据
bytes[i] += 256;
}
}
// 生成jpeg图片
OutputStream out = new FileOutputStream(imgFilePath);
out.write(bytes);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}
}
然后在手机端加载:
至此,问题解决!