Android webView字体突然变小的原因及解决

背景

最近,端内在做 webView 统一的时候,个性签名中的 WebView 替换为 CustomWebView 之后,发现字体突然变小。

一开始不知道是什么原因,通过二分法查找最近的提交,排查之后,发现是 SignatureWebView 的继承关系从 WebView 修改为 CustomWebView。revert 之后就正常了。

于是,我问自己,为什么会这样呢?

原因分析

我们知道,WebViewSetting 里面是可以修改 WebView 的一些默认设置的。

阅读官方文档,发现 setLoadWithOverviewMode,setUseWideViewPort 这两个方法看起来跟 WebView 缩放相关。

于是尝试把 setLoadWithOverviewMode 改为 false,很神奇,竟然正常了。

setLoadWithOverviewMode

这个方法的作用,简单来说,就是是否根据屏幕宽度自适应

Sets whether the WebView loads pages in overview mode, that is, zooms out the content to fit on screen by width. This setting is taken into account when the content width is greater than the width of the WebView control, for example, when getUseWideViewPort() is enabled. The default is false.

developer.android.com/reference/a…

这个问题解决之后,我心中又有这样的疑问,为什么别的地方没有问题,只有个性签名这里的 WebView 有问题。

带着这个疑问,我再次去浏览代码,发现个性签名里面 Webview 加载的网页,是自己拼接的 html。debug 之后,发现网页代码大概是这样的

<span style="word-wrap:break-word;font-family:system-ui;font-size:16px;color:#888888;">Https://www.baidu.com</span>

可以看到里面字体的单位是 px,跟 Android 的 dp px 有点像,是不是没作屏幕适配?

搜索发现 Web 网页的代码适配单位是 rem,有点类似于 dp。

Web 网页在适配分辨率的时候,通常会设置 viewport 属性

于是我尝试在代码里面加了这样的代码,发现 SignatureWebView 显示个性签名又正常了。

parsedHtml += "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover\">";

Web 网页字体的适配规则,这里就不班门弄斧了,有兴趣的可以自行搜索。

端内其他地方排查

我们知道,加载自定义 html,通常需要调用 loadDataWithBaseURL 方法,查看端内调用的地方,发现其他都是正常的。只有这个奇葩 SignatureWebView ,自己拼接的 html 没有加 viewport 属性,进行适配

总结

  1. 如果 html 是自己拼接的,并且像素是 px,不要设置 WebViewSetting 的 setLoadWithOverviewMode ,setUseWideViewPort(默认属性是 false),否则字体可能显示不正常,偏大或者偏小
  2. 如果 html 是自己拼接的,并且像素是 px,当我们设置 WebViewSetting 的 setLoadWithOverviewMode ,setUseWideViewPort 为 true(根据屏幕自适应),那么我们需要设置 html 的 viewport 规则,否则可能显示不正常
  3. html 如果是自己拼接的,需要注意适配规则,像个人签名这种,用 webView 承载自己拼接的 html ,防止踩坑

WebView 字体常见的其他坑

手机设置字体大小导致h5页面在webview中变形

出现这个问题的原因是

  1. 默认浏览器中的内容是不受系统字体大小设置控制的,至少我遇到的几台手机都是这样的情况。
  2. 某些机型 WebView 字体的大小是受手机系统字体大小控制的

这个通常有两种解决方案。

Web js 网页解决方案

  1. 一般,我们动态计算好html的font-size之后,我们就啥都不干了,就走了。
  2. 但是,我们现在知道了,我们设置的大小不一定是真实的大小,所以,我们需要在设置完字体大小之后,再去重新获取一下html的font-size,看看实际的这个值,和我们设置的是不是一样。
  3. 如果不一样,就要根据比例再设置一次。
function htmlFontSize(){
 var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
 var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
 var width = w > h ? h : w;
 width = width > 720 ? 720 : width
 var fz = ~~(width*100000/36)/10000
 document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz +"px";
 var realfz = ~~(+window.getComputedStyle(document.getElementsByTagName("html")[0]).fontSize.replace('px','')*10000)/10000
 if (fz !== realfz) {
  document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz * (fz / realfz) +"px";
 }
}

客户端 WebView 禁止缩放

Android WebView 是可以通过 WebSettings 禁止网页字体缩放的,可以通过 setTextZoom 方法解决

webview.getSettings().setTextZoom(100)

小结

这篇文章主要是记录 bug 的一个解决过程,技术含量不高,但是有一定的参考价值。尤其是 bug 的解决思路。

  1. 线上突然出现问题,一直找不出问题,尝试一下二分法,逐步缩小范围。
  2. 有时候,我们找到解决方案,却不一定知道原因是什么,这时候,可以多问一下自己,背后的原因是什么?在排查的过程中,我们会逐渐培养自己的一套问题解决思路,听起来很虚,但是确实存在的。
  3. 知道原因之后,我们可以继续再进一步排查一下,项目中其他模块是不是也存在这样的问题。
  4. 以后要怎么规避之类问题?写个 wiki 或者博客记录一下

以上就是Android webView字体突然变小的原因及解决的详细内容,更多关于Android webView字体突然变小的资料请关注我们其它相关文章!

(0)

相关推荐

  • 解决Android webview设置cookie和cookie丢失的问题

    Android页面嵌套了一个h5,H5页面内部有用户登陆页面,发现h5页面的登陆功能无法使用,一直登陆失败.和web那边商量一会,发现js写入的cookie丢失了.所有需要Android这边在重写写入一次. mWebView = view.findViewById(R.id.mall_view); settings = mWebView.getSettings(); settings.setJavaScriptEnabled(true); settings.setLoadsImagesAutom

  • 详解Android WebView监听console错误信息

    根据需求,我们要拿到h5的错误信息,并将error信息进行上报.查询了下Android WebView的API发现了WebChromeClient这个方法可以满足要求: @Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) { //获取log的级别 switch (consoleMessage.messageLevel()){ case ERROR://将error信息上报到服务端 LogUtil.log

  • Android webView如何输出自定义网页

    这次来使用webview输出网页型数据.因为这样的数据好使用富文本编辑器,有各种各样的拓展. 上代码: package controller.hzl.com.testcall; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.webkit.WebView; import android.webkit.We

  • Android实现WebView点击拦截跳转原生

    1. 首先设置Web视图 webview.setWebViewClient(new MyWebViewClient()); webview1.setWebViewClient(new MyWebViewClient()); 2. 拦截点击的链接,跳转到对应的页面 // 监听 所有点击的链接,如果拦截到我们需要的,就跳转到相对应的页面. private class MyWebViewClient extends WebViewClient { @Override public boolean sh

  • Android webview注入JS代码 修改网页内容操作

    今天开发的时候遇到一个需求,就是需要隐藏webview的元素,鼓捣了半天 在stack overFlow找到了解决办法 在此记录一下 final WebView webview = (WebView)findViewById(R.id.browser); webview.getSettings().setJavaScriptEnabled(true); webview.setWebViewClient(new WebViewClient() { @Override public void onP

  • Android 解决WebView多进程崩溃的方法

    问题 在android 9.0系统上如果多个进程使用WebView需要使用官方提供的api在子进程中给webview的数据文件夹设置后缀: WebView.setDataDirectorySuffix(suffix); 否则将会报出以下错误: Using WebView from more than one process at once with the same data directory is not supported. https://crbug.com/558377 1 com.a

  • Android WebView通过动态的修改js去拦截post请求参数实例

    需求背景: 需要在用户点击提交按钮的时候拦截用户提交的数据. 遇到的问题: 1.页面不是自家前端做的,不能修改网页中的代码 2.要拦截的请求不是get请求,而是一个post请求 (难点在于:如果拦截的请求是get请求的话,我只需要拿到url,将后面拼接的参数键值对取出来就好了,但是post请求的参数键值对我们是看不到的...) 解决重点: 重写webViewClient的shouldInterceptRequest这个方法 1.这个方法是API21以后才出现的,还有一个过时的方法也要重写,不要忘

  • Android 中 WebView 的基本用法详解

    加载 URL (网络或者本地 assets 文件夹下的 html 文件) 加载 html 代码 Native 和 JavaScript 相互调用 加载网络 URL webview.loadUrl(https://www.baidu.com/); 加载 assets 下的 html 文件 webview.loadUrl(file:///android_asset/test.html); 加载 html 代码 // 两个代码差不多 // 偶尔出现乱码 webview.loadData(); // 比

  • 在Android环境下WebView中拦截所有请求并替换URL示例详解

    需求背景 接到这样一个需求,需要在 WebView 的所有网络请求中,在请求的url中,加上一个xxx=1的标志位. 例如 http://www.baidu.com 加上标志位就变成了 http://www.baidu.com?xxx=1 寻找解决方案 从 Android API 11 (3.0) 开始,WebView 开始在 WebViewClient 内提供了这样一条 API ,如下: public WebResourceResponse shouldInterceptRequest(Web

  • Android中webView加载H5绑定cookie实例

    简介: 我最近在做项目的时候遇到了这种情况: 1.需要用WebView实现一个H5的登陆注册. 2.大赛报名,用H5实现.这些情况下,我需要把cookie传给服务器,让其判断当前账户是否登陆成功.查阅了一些资料后,终于搞定了. 1. 给一个加载的链接设置cookie private void syncCookie(String url) { try { CookieSyncManager.createInstance(mWvSignUp.getContext());//创建一个cookie管理器

随机推荐