LWDW!

Learn the work from doing the work🍺

WebView的世界
Posted on 2023-12-06

当H5遇上WebView,我们会遇到哪些常见的需求/问题?

  1. 颜色适应
  2. APP调起
  3. 数据通信
  4. 兼容性

颜色适应

可以细分为两种情形:

  1. APP内的同一处页面需要支持不同颜色展示,常见于APP支持设置亮色、暗色主题
  2. APP内不同处用到了同一页面,但是需要该页面可支持多种主题色。常见为通用H5在多处被复用,甚至在多APP内被复用。

场景1:

关键词:prefers-color-scheme

通过这个媒体查询,H5可以定制一套dark样式。

但你就不得不问了,这个媒体查询什么时候生效?WebView可以控制么?

一般在默认情况下,prefers-colors-scheme会跟随系统主题生效。

那WebView能进一步控制么?毕竟很多的App是允许用户手动设置浅色/深色模式的。

答案是可以的。建议参考这两篇指南:

上述指南还包含三个进阶知识点:

  1. H5增加meta tag <meta name="color-scheme" content="dark light" /> 可以更好的帮助APP使用正确的颜色配置。
  2. 即使没有设置prefers-color-schema,WebView其实也支持通过算法为H5生成一套深色外观。
  3. 在CSS中设置color-scheme可以帮助滚动条、Textarea元素等自带样式的控件应用正确的外观。

e.g. hacker news自动生成的深色外观:

hacker news1.png

hacker news2.png

场景2:

场景2需要为页面做动态样式渲染,也就是说WebView需要给H5传样式参数,来得到不同的样式。

那么参数怎么传,以及H5怎么接收参数,怎么渲染呢?

其实WebView和H5之间通信是之后的话题,考虑到这里只需要WebView单向的往H5传参,最常见的想法就是:

  1. URL search parameters
  2. JS bridge

这些方案都行,但用它们做样式动态设置其实并不太好,因为一定会产生肉眼可见的样式变化延迟——参数的接收和生效都是在客户端进行的,JS后置,这个延迟一般能有几百毫秒。

更好的方案?你可能已经想到了,我个人觉得动态路由+SSR非常适合这种场景。使用动态路由就可以在服务端完成参数的接收,那么返回的HTML就是参数已经生效的版本,一切都会显得非常的丝滑。

APP调起

唤端:

  • IOS:
    • URI Scheme,不推荐,理由有
      • 无法实际判断唤端成功与否,一般通过页面计时来猜测是否成功,体验并不好
      • 失败的时候,会提示不认得这个链接,看起来像个报错
    • Universal link,目前官方最推荐的方法
  • Android
    • URI Scheme似乎表现尚可

数据通信,方法互相调用

  1. JS bridge是比较常见的方案,JS需要将方法暴露到window上,然后flutter就可以调用该方法。
  2. Flutter的WebView插件InAppWebview,本身提供了handler进行数据通信

兼容性

当遇到兼容性问题的时候,首先我们关心的就是WebView内核版本。

Android

安卓的WebView是一个独立的组件。因此当遇到兼容问题的时候,首先要查看它的版本。

一般可以在设置中打开开发者模式后,找到对应的信息:

WebView version.png

顺带一提,升级系统WebView的方式:

  • 大陆的安卓手机系统一般是通过升级系统版本随带更新WebView版本。
  • 支持Google服务的安卓手机系统可通过Google Play单独升级系统WebView版本。