searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

使用 AndroidX 增强 WebView 的能力-1

2024-06-17 04:08:58
0
0

在应用开发过程中,为了在多个平台上保持一致的用户体验和提高开发效率,许多应用选择使用 H5 技术。在 Android 平台上,通常使用 WebView 组件来承载 H5 内容以供展示。

 

WebView 存在的问题
自 Android Lollipop 起,WebView 组件的升级已经独立于 Android 平台。然而,控制 WebView 的 API (android.webkit) 仍然与平台升级相关。这意味着应用开发者只能使用当前平台所定义的接口,而无法充分利用 WebView 的全部能力。例如:WebView.startSafeBrowsing API 在 Android 8.1 上被添加,该 Feature 由 WebView 提供,即使我们在 Android 7.0 更新 WebView 拥有了该 Feature,由于 Android 7.0 没有 WebView.startSafeBrowsing API,我们也没办法使用该功能。
WebView 的实现基于 Chromium 开源项目,而 Android 则基于 AOSP 项目,这两个项目有着不同的发布周期,WebView 往往一个月就可以推出下一个版本,而 Android 则需要一年的时间,对于 WebView 新增的 Feature 我们最迟需要一年才能使用。

AndroidX Webkit 的出现

为了解决上面平台能力和 WebView 不匹配的问题,我们可以独立于平台之外定义一套 WebView API,并让它随着 WebView 的 Feature 更新 API,这样解决了现有的问题却导入了另一个问题——如何将新定义的 WebView API 和 WebView 进行衔接。
从应用开发的角度,系统 WebView 难以修改,自己编译定制一个 WebView 并随着 APK 提供是一个很好方案。这时候,我们可以轻松地解决衔接问题,并能够按照需求,任意增改 Feature 而不必等官方更新。同时解决了兼容问题和 WebView 内核碎片化的问题。腾讯 X5,UC U4 等都是这个方案。维护一份 WebView 并不是一件容易的事,需要投入更多的人力支持,因为将 WebView 打入包中,还伴随着包体积的急剧增加。
从 Android 官方的角度,可以推动 WebView 上游支持该 WebView API,而这正是 AndroidX Webkit 的解决方案。Android 官方将定义的 WebView API 放置到 AndroidX Webkit 库,以支持频繁的更新,并在 WebView 上游增加 "胶水层" 与 AndroidX Webkit 进行衔接,这样在旧版的 Android 平台上,只要安装了拥有 "胶水层代码的 WebView,也就拥有了新版平台的功能。
"胶水层" 是在某个版本之后才支持的,旧版本的 WebView 内核并不支持,这也是为什么在调用之前始终应该检查 isFeatureSupported

 

AndroidX Webkit 的功能

初步了解了 AndroidX Webkit 的产生和实现原理,下面带领大家看一下它都提供了哪些新能力能够增强我们的 WebView。

向下兼容

如上文分析,AndroidX Webkit 提供了向下的兼容,如下面代码所示,由 WebViewCompat 提供兼容的接口调用。
需要注意的是在调用之前对 WebViewFeature 的检查,对于每个 Feature,AndroidX Webkit 会取平台和 WebView 所提供 Feature 的并集,在调用某个 API 之前必须进行检查,如果平台和 WebView 均不支持该 API 则将抛出 UnsupportedOperationException 异常。
// Old code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
   WebView.startSafeBrowsing(appContext, callback);
}

// New code:
if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) {
   WebViewCompat.startSafeBrowsing(appContext, callback);
}
如果我们扒开 WebViewCompat 的外衣查看它的源码 (如下所示),会发现如果在当前版本 Platform API 提供了接口,就会直接调用 Platform API 的接口,而对于低版本,则由 AndroidX Webkit 和 WebView 的 "通道" 提供服务。
// WebViewCompat#startSafeBrowsing
public static void startSafeBrowsing(@NonNull Context context,
        @Nullable ValueCallback<Boolean> callback) {
    ApiFeature.O_MR1 feature = WebViewFeatureInternal.START_SAFE_BROWSING;
    if (feature.isSupportedByFramework()) {
        ApiHelperForOMR1.startSafeBrowsing(context, callback);
    } else if (feature.isSupportedByWebView()) {
        getFactory().getStatics().initSafeBrowsing(context, callback);
    } else {
        throw WebViewFeatureInternal.getUnsupportedOperationException();
    }
}
对比上面的代码,使用平台 API (old code) 时仅可以支持 90% 的用户,而使用 AndroidX Webkit (new code) 则可以覆盖大约 99% 的用户。
0条评论
0 / 1000
wbq
17文章数
0粉丝数
wbq
17 文章 | 0 粉丝