Android -- WebView之loadData加载html字符串显示网页

目录
  • 前言
  • 1. loadUrl 加载网页地址
  • 2. loadData 加载Html字符来显示网页
  • 3. loadDataWithBaseURL
  • 4. 总结

前言

最近在给一个老项目做64位so文件的适配,当应用发布到应用市场上后,用户反馈64位手机上的网页加载不出内容,但32位的手机上是正常的。

我的第一反应是:网页加载不出内容,那不是网页没做好适配嘛!(把锅甩出去)

后经多方细细排查,是WebView的锅。。。(锅又回来了。。)

WebView 加载网页的方法有三种:loadUrl、loadData、loadDataWithBaseURL,下面只记录本人在这三个方法上遇到的问题,具体WebView的基础使用请参考:

Android – WebView 与 JS 交互方式总结
Android – WebView 支持文件下载的几种方式

1. loadUrl 加载网页地址

先写个网页用于加载测试,test2.html(路径:assets/webpage/test2.html):

<html><body><h1>Hello, WebView</h1><p style="color: #f00">This is a simple HTML page loaded into a WebView.</p>
</body></html>

loadUrl(String url) 加载网页地址:

....
//这里省略WebView的其他基础设置
mWebView.loadUrl("file:///android_asset/webpage/test2.html");
....

显示的内容:
在这里插入图片描述
使用 loadUrl(String url) 加载网页,在32位和64位的手机上显示都没有问题。

我的线上应用不是通过url这种方式加载网页的,是通过加载Html字符来加载网页的。

2. loadData 加载Html字符来显示网页

loadData(String data, String mimeType, String encoding)

官方定义:

Load the given data into the WebView. This will load the data into WebView using the data: scheme. Content loaded through this mechanism does not have the ability to load content from the network.
将给定的数据加载到WebView中。这将使用 data: scheme 将数据加载到WebView中。通过此机制加载的内容无法从网络加载内容。

字面意思就是此方法是通过读取Html字符来显示网页的。

/*** 读取 Html字符* @param fileName 文件名*/
private String readAsset(String fileName) {AssetManager assetManager = getAssets();StringBuilder stringBuilder = new StringBuilder();try (InputStream inputStream = assetManager.open(fileName);BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {String line;while ((line = reader.readLine()) != null) {stringBuilder.append(line);}} catch (IOException e) {e.printStackTrace();return null;}return stringBuilder.toString();
}private void loadUrl() {.......StringBuilder stringBuilder = new StringBuilder();//读取Html字符内容stringBuilder.append(readAsset("webpage/test2.html"));mWebView.loadData(String.valueOf(stringBuilder), "text/html; charset=UTF-8", null);.......
}

在32位的手机上显示正常,64位的个别手机显示如下:
(线上反馈,Android 10 以上的手机出问题的较多)
在这里插入图片描述

由图可知,Html中带颜色的标签p的内容未显示出来。

回到官网看下loadData的入参说明:

data

A String of data in the given encoding. The date must be URI-escaped – ‘#’, ‘%’, ‘’, ‘’ should be replaced by %23, %25, %27, %3f respectively.

mimeType

The MIMEType of the data. i.e. text/html, image/jpeg

encoding

The encoding of the data. i.e. utf-8, base64

data:此入参中不能出现特殊字符 ‘#’, ‘%’, ‘’, ‘’ ,需要将其替换成 %23, %25, %27, %3f。

这就为内嵌的css制造了麻烦,因为css中经常使用这4种符号,就如 test2.html 中使用’#'设置了颜色:color: #f00 。

根据官网文档,将 ‘#’ 替换成 ‘%23’:

....StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(readAsset("webpage/test2.html"));
mWebView.loadData(String.valueOf(stringBuilder).replace("#", "%23"), "text/html; charset=UTF-8", null);....

这样在64位安卓10以上的手机上就能正常显示了,同时也不影响32位的手机。

在正式的应用里,后台返回的Html字符数据结构都是很复杂的,里面包含css,script等内容,里面用到特殊字符的频率都很大,如果每次加载之前都要对Html做特殊字符替换处理的话,难免会出现乱码等其他问题。

所以这里就需要使用 loadDataWithBaseURL

3. loadDataWithBaseURL

loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)

官网资料:

Load the given data into the WebView, use the provided URL as the base URL for the content. The base URL is the URL that represents the page that is loaded through this interface. As such, it is used to resolve any relative URLs. The historyUrl is used for the history entry.
将给定的数据加载到WebView中,使用提供的URL作为内容的基本URL。基本URL是表示通过此接口加载的页面的URL。因此,它用于解析任何相对URL。historyUrl用于历史条目。

Note for post 1.0. Due to the change in the WebKit, the access to asset files through “file:///android_asset/” for the sub resources is more restricted. If you provide null or empty string as baseUrl, you won’t be able to access asset files. If the baseUrl is anything other than http(s)/ftp(s)/about/javascript as scheme, you can access asset files for sub resources.
1.0 后的注释。由于 WebKit 的更改,通过"file:///android_asset/"这种方式子资源受到更多的限制。如果你提供null 或空字符串作为baseUrl,你将无法访问资产文件;如果baseUrl不是http(s)/ftp(s)/about/javascript 作为 scheme,你可以访问子资源的文件。

入参说明:

baseUrl

Url to resolve relative paths with, if null defaults to “about:blank”

data

A String of data in the given encoding.

mimeType

The MIMEType of the data. i.e. text/html. If null, defaults to “text/html”

encoding

The encoding of the data. i.e. utf-8, us-ascii

historyUrl

URL to use as the history entry. Can be null.

从入参上看,loadDataWithBaseURL中并没有对 data 做特殊字符的限制。

....StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(readAsset("webpage/test2.html"));
mWebView.loadDataWithBaseURL("", String.valueOf(stringBuilder), "text/html", "UTF-8", "");....

所以,最终使用 loadDataWithBaseURL 完美解决了64位安卓10以上部分手机网页加载不出来的问题。

4. 总结

一开始线上反馈这个问题的时候,我也没有想到是loadData的问题。正式的应用上返回的Html是相当的复杂,里面有Html、css、好几个script,将这些字符内容打印出来在文档上显示时,看着就头疼。(非网页专业的,看着肯定头疼)

想到的最笨的方法,就是将Html、css、script这几个标签拆分开,化复杂为简洁。先将css和script的代码删除,只留下Html,看看 WebView 是否能正常加载出来。结果这一步就不能正常加载,然后我将 Html 中的样式全部去除,只留下文字部分,这样是可以正常显示的,说明问题出在样式上。然后将样式一点点加回到Html中,最终找到是颜色中 ‘#’ 影响了页面的显示。

虽然方法有点儿笨,但好在能排查到问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/63792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker在Ubuntu和CentOS系统下的安装

目录 1. 各版本平台支持情况2. 在Ubuntu系统下安装docker3. 常见报错4. Docker的镜像源修改5. Docker目录修改6. 在CentOS系统下安装docker 1. 各版本平台支持情况 &#xff08;1&#xff09;平台支持情况如下&#xff1a; Server 版本 桌面版本 2. 在Ubuntu系统下安装docker…

Ansible-Playbook基础学习

一.Ansible Playbook基本介绍 1.Playbook 介绍 Ansible Playbook 是 Ansible 的核心组件之一&#xff0c;它是一个用于配置管理、应用部署和任务自动化的文本文件&#xff0c;使用 YML格式编写。YML 的语法简洁明了&#xff0c;易于阅读和编写&#xff0c;使得用户可以方便地…

基于PHP课堂签到系统的设计与实现

摘 要 随着教育业的迅速发展和学生人数的不断增加&#xff0c;导致在班级登记制度中传统的“点到”方式不能适应学校的实际需要。从而需要设计一个好的课堂签到系统将会对课堂签到管理工作带来事半功倍的效果。文章着重介绍了基于实践应用的班级签到系统的开发流程&#xff0c…

【智体OS】官方上新发布智体电视:基于rtpc和rttouchpad实现智体电视的手机遥控-可安装任意PC应用用于智体电视

【智体OS】官方上新发布智体电视&#xff1a;基于rtpc和rttouchpad实现智体电视的手机遥控-可安装任意PC应用用于智体电视 dtns.network是一款主要由JavaScript编写的智体世界引擎&#xff08;内嵌了three.js编辑器的定制版-支持以第一视角浏览3D场馆&#xff09;&#xff0c;…

保姆级教学 uniapp绘制二维码海报并保存至相册,真机正常展示图片二维码

一、获取二维码 uni.request({url: https://api.weixin.qq.com/wxa/getwxacode?access_token${getStorage("token")},responseType: "arraybuffer",method: "POST",data: {path: "/pages/index/index"},success(res) {// 转换为 Uint…

Vue.createApp的对象参数

目录 template 属性 data 属性 methods 属性 疑问 function 函数的两种写法 methods 属性中 this 的指向 总结 Vue 实例是通过 Vue.createApp() 创建的&#xff0c;该函数需要接收一个对象作为参数&#xff0c;该对象可添加 template、data、methods 等属性。 template …

LLM大语言模型私有化部署-OpenEuler22.03SP3上容器化部署Ollama与OpenWebUI

背景 你是不是也有私有化部署大模型的需求&#xff1f;如今有了 Ollama &#xff0c; HuggingFace &#xff0c; ModelScope 等开源平台&#xff0c;我们可以非常方便地搭建一个属于自己的大模型&#xff0c;如果网速给力&#xff0c;真是分分钟~~。简单起见&#xff0c;这篇文…

Linux——rootfs根文件系统构建

根文件系统也叫做rootfs FATFS这类的文件系统属于Linux内核的一部分&#xff0c;属于软件代码&#xff0c;所以ROOTFS不等于FATFS。 Linux的根文件系统实际上是一个文件夹或者叫目录&#xff0c;这个目录下会有许多子目录&#xff0c;这些目录中存放许多Linux运行所必须的文件…

go语言的成神之路-标准库篇-os标准库

一、权限 在操作系统&#xff08;OS&#xff09;中&#xff0c;标准库的权限管理是非常重要的&#xff0c;它确保了不同用户和进程能够安全地访问系统资源。以下是一些常见的权限概念和说明&#xff1a; 1.用户权限 用户ID&#xff08;UID&#xff09;&#xff1a;每个用户在…

【OpenCV】直方图

理论 可以将直方图视为图形或曲线图&#xff0c;从而使您对图像的强度分布有一个整体的了解。它是在X轴上具有像素值(不总是从0到255的范围)&#xff0c;在Y轴上具有图像中相应像素数的图。 这只是理解图像的另一种方式。通过查看图像的直方图&#xff0c;您可以直观地了解该…

【PlantUML系列】用例图(三)

目录 一、组成部分 二、典型案例 一、组成部分 参与者&#xff08;Actors&#xff09;&#xff1a;使用关键字 actor 后跟参与者的名称。用例&#xff08;Use Cases&#xff09;&#xff1a;使用关键字 usecase 后跟用例的名称和编号&#xff08;可选&#xff09;。系统边界…

Transformer部分知识点解释

传统Transformer 经典QKV算法 Transformer架构的优势与问题 万能模型&#xff0c;直接套用&#xff0c;代码实现简单&#xff0c;现成例子一大片并行的&#xff0c;比LSTM快&#xff0c;全局信息丰富&#xff0c;注意力机制效果好长序列中attention需要每一个点跟其他点计算(…

聚类及Python下实现 K-means 算法

聚类 聚类是无监督学习中的一种重要方法&#xff0c;旨在将数据集中相似的数据对象划分到同一个簇中&#xff0c;使得不同簇之间的数据对象差异尽可能大。在大数据环境下&#xff0c;聚类可以帮助挖掘数据中的隐藏结构和模式&#xff0c;应用场景十分广泛&#xff0c;比如在客…

LabVIEW调用Thorlabs的动态库进行开发

Thorlabs 产品在科研与生产领域中的应用广泛&#xff0c;当需要基于LabVIEW 进行二次开发时&#xff0c;可按照以下方法操作&#xff0c;以充分发挥设备性能并满足特定的项目需求。 创建 Kinesis LabVIEW 项目文件和文件夹 更详细的说明参见附件 在 LabVIEW 的启动界面中选择…

三、Zookeeper

Zookeeper 三、Zookeeper3.1什么是zookeeper?3.2为什么需要zookeeper3.3Zookeeper基本运行流程3.4Zookeeper数据模型3.5Zookeeper主要角色3.6Zookeeper工作原理3.7Zookeeper节点数据操作流程三、Zookeeper 3.1什么是zookeeper? ZooKeeper是一个分布式的,开放源码的分布式应…

实现盘盈单自动化处理:吉客云与金蝶云星空数据对接

盘盈单103v2对接其他入库&#xff1a;吉客云数据集成到金蝶云星空 在企业信息化管理中&#xff0c;数据的高效流转和准确性至关重要。本文将分享一个实际案例&#xff0c;展示如何通过轻易云数据集成平台&#xff0c;将吉客云的数据无缝对接到金蝶云星空&#xff0c;实现盘盈单…

vue:构造结构,塞入数据:结构不变,数据改变

1. 引入vue 2. 创建页面容器&#xff0c;让vue去管理这个容器 3. 双向绑定 4. 单向绑定 5. 操作容器&#xff08;数据模型&#xff09;里的数据 5. 单向绑定的简写 6. v-if和v-else 6. v-if和v-show的区别&#xff1a; v-if要重新渲染界面&#xff0c;v-show只需要改一下元素属…

CountDownLatch阻塞后countDown未执行会如何?

背景 某项目封装了 Kafka 消费者 API&#xff0c;根据传递的消费者线程数&#xff0c;创建 N 个消费者线程同时消费对应 topic 的数据&#xff0c;并在线程启动后收集到全局列表中&#xff0c;方便在程序调用 stop 流程时逐个停止。 主控类在创建 Kafka 消费线程时使用了 Cou…

NLP与LLM的工程化实践与学习思考 - 说说知识图谱

NLP与LLM的工程化实践与学习思考[24年半年工作总结] - 说说知识图谱 0 真的就是先说说1 为什么知识图谱什么是知识图谱&#xff1f;基于图的数据结构&#xff1f;基于数据结构的图&#xff1f;知识图谱的技术要点两个技术维度&#xff1a;知识、图七个技术要点&#xff1a;表示…

【CVE-2024-5660】ARM CPU漏洞:硬件页面聚合(HPA)安全通告

安全之安全(security)博客目录导读 目录 一、概述 二、修改历史 三、什么是硬件页面聚合&#xff1f; 四、修复解决 一、概述 在一些基于arm的cpu中发现了一个问题&#xff0c;该问题可能允许修改的、不受信任的客户机操作系统&#xff08;guest OS&#xff09;危及某些H…