本指南介绍了 Jetpack Webkit 库的优势、运作方式以及如何在项目中实现该库。
概览
WebView 是 Android 开发的重要组成部分,但由于不同 Android OS 版本的功能不一致,因此有时很难管理。每个 Android OS 版本都提供一组固定的 WebView API。由于 Android 的发布节奏比 WebView 慢,因此 Android API 可能无法涵盖所有可用的 WebView 功能。这会导致功能发布速度变慢,并增加测试费用。
Jetpack Webkit 通过充当兼容性层并利用用户设备上最新的 WebView APK 来解决这些问题。它还包含仅在此库中提供的新型现代 API。
为何使用 Jetpack Webkit?
除了提供跨版本兼容性之外,Jetpack Webkit 还提供新型现代 API,这些 API 可以简化开发并改进应用的功能:
启用现代身份验证:WebView 可以无缝处理 WebAuthn 等现代 Web 身份验证标准,从而实现基于通行密钥的登录。借助
androidx.webkit库,您可以使用WebSettingsCompat.setWebAuthenticationSupport()方法完全控制此集成,该方法可用于配置应用所需的支持级别。提升性能:使用
prefetchUrlAsync、prerenderUrlAsync和setBackForwardCacheEnabled等 API,针对应用的使用情形微调 WebView 的性能。提高稳定性:恢复停滞或无响应的渲染器进程 而不会发生崩溃。如需了解详情,请参阅
WebViewRenderProcess#terminate()。提供对浏览数据的精细控制:如需删除 WebView 为特定源存储的浏览数据,请使用
WebStorageCompat类。
了解组件
如需有效使用 Jetpack Webkit,您必须了解以下组件之间的关系:
Android System WebView:这是基于 Chromium 的渲染引擎,Google 会定期通过 Google Play 商店以与 Chrome 相同的节奏对其进行更新。它包含最新的功能,并为所有 WebView API 提供底层实现代码。
框架 API (
android.webkit) :这些 API 固定到特定的 Android OS 版本。例如,Android 10 上的应用只能访问该版本发布时可用的 API。因此,它无法使用在最近更新中添加到 WebView APK 的新功能。例如,如需使用WebView#getWebViewRenderProcess()获取无响应的渲染器的句柄,您只能在 Android 10 及更高版本上调用此方法。Jetpack Webkit 库 (
androidx.webkit) :这是一个捆绑在应用中的小型库。此库充当调用 WebView APK 的桥梁,而不是调用 Android 平台中定义的 API,后者具有固定的 OS 版本。这样,即使应用安装在运行旧版 OS(如 Android 10)的设备上,应用也可以使用最新的 WebView 功能。例如,WebViewCompat.getWebViewRenderProcess()的工作方式与框架 API 类似,但它也可以在 Android 10 之前的所有 OS 版本上调用。
如果框架和 Jetpack Webkit 中都有某个 API,我们建议您选择 Jetpack Webkit 版本。这有助于确保在最广泛的设备范围内实现一致的行为和兼容性。
Jetpack Webkit 和 APK 交互
Jetpack Webkit 中的 API 分为两部分实现:
静态 Jetpack Webkit:静态 Jetpack Webkit 库包含 负责实现 API 的少量代码。
WebView APK:WebView APK 包含大部分代码。
您的应用会调用 Jetpack Webkit API,然后该 API 会调用 WebView APK。
虽然您可以控制应用中的 Jetpack Webkit 版本,但无法控制用户设备上的 WebView APK 更新。一般来说,大多数用户都拥有最新版本的 WebView APK,但您的应用仍必须谨慎,不要调用特定版本的 WebView APK 不支持的 API。
Jetpack Webkit 还抽象出了手动检查 WebView 版本的需求。
如需确定某项功能是否可用,请检查其功能常量。例如,WebViewFeature.WEB_AUTHENTICATION。
协同工作方式
Jetpack Webkit 弥合了静态框架 API 和经常更新的 WebView APK 之间的差距。当您将 Jetpack Webkit API 与功能检测模式搭配使用时,该库会执行检查,以查看用户设备上安装的 WebView APK 是否支持该功能。这样做的好处是不需要检查 Android OS(框架)版本。
如果 WebView APK 的版本足够新,该库会调用该功能。 否则,它会报告该功能不可用,从而防止应用崩溃,并让您能够优雅地处理这种情况。
比较 Jetpack Webkit 和框架 API
本部分比较了使用和不使用 Jetpack Webkit 库的实现方法:
启用现代身份验证 (WebAuthn)
不使用 Jetpack Webkit
无法通过框架 API 实现。
使用 Jetpack Webkit
利用 WebViewFeature.WEB_AUTHENTICATION 进行兼容性检查。
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_AUTHENTICATION)) {
WebSettingsCompat.setWebAuthenticationSupport(
webView.settings,
WebSettingsCompat.WEB_AUTHENTICATION_SUPPORT_FOR_APP
)
}
删除来源的数据(特定于网站的存储空间)
不使用 Jetpack WebKit
没有用于清除特定来源数据的直接 API。通常需要清除所有数据。
使用 Jetpack WebKit
使用兼容性 API 进行精确的数据删除。您可以使用以下任一选项:
WebStorageCompat.getInstance().deleteBrowsingData()
或
WebStorageCompat.getInstance().deleteBrowsingDataForSite()
获取 WebView 版本
不使用 Jetpack WebKit
使用标准框架类。
val webViewPackage = WebView.getCurrentWebViewPackage()
使用 Jetpack WebKit
使用兼容性层进行更安全的检索。
val webViewPackage = WebViewCompat.getCurrentWebViewPackage()
处理无响应的渲染器(渲染器客户端)
不使用 Jetpack WebKit
使用标准框架方法。
webView.setWebViewRenderProcessClient(myClient)
使用 Jetpack WebKit
使用 WebViewCompat 和功能检查来设置客户端。
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE)) {
WebViewCompat.setWebViewRenderProcessClient(webView, myClient)
}
如需了解详情,请参阅 androidx.webkit 参考文档。
将 Jetpack Webkit 集成到代码中
使用 Jetpack Webkit 可以增强标准 WebView 类的功能,但它不会完全替换原始 WebView 类。
您可以继续使用 android.webkit.WebView 类。您可以将其添加到 XML 布局中,并在代码中获取对实例的引用。如需访问标准框架功能,您仍然可以直接在 WebView 实例或其设置对象上调用方法。
如需访问现代功能,您可以使用 Jetpack Webkit 提供的静态帮助程序方法,例如 WebViewCompat 和 WebSettingsCompat。您将现有的 WebView 实例传递给这些方法。
Kotlin
import android.webkit.WebView
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
// You still get your WebView instance the standard way.
val webView: WebView = findViewById(R.id.my_webview)
// To enable a modern feature, you pass that instance to a Jetpack Webkit helper.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)
}
Java
import android.webkit.WebView;
import androidx.webkit.WebSettingsCompat;
import androidx.webkit.WebViewFeature;
// You still get your WebView instance the standard way.
WebView webView = findViewById(R.id.my_webview);
// To enable a modern feature, you pass that instance to a Jetpack Webkit helper.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON);
}
实现 Jetpack Webkit
如需实现 Jetpack Webkit,请使用以下过程。
第 1 步:添加依赖项
在模块的 build.gradle.kts 或 build.gradle 文件中,添加
以下依赖项以添加 Jetpack Webkit:
Groovy
dependencies { implementation "androidx.webkit:webkit:1.16.0" }
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.16.0") }
Jetpack Webkit 包含精简型封装容器,因此对应用大小的影响很小。
第 2 步:采用功能检测模式
如需防止在调用不可用的 API 时发生崩溃,请使用功能检查。我们建议您使用功能检查封装每个 API 调用,并考虑在 API 不可用时使用回退逻辑。
我们建议您使用以下模式来使用现代 WebView API:
Kotlin
import android.webkit.WebView
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
val webView: WebView = findViewById(R.id.my_webview)
// Before you use a modern API, first check if it is supported.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
// If the check passes, it is safe to call the API.
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)
} else {
// Optionally, provide a fallback for older WebView versions.
}
Java
import android.webkit.WebView;
import androidx.webkit.WebSettingsCompat;
import androidx.webkit.WebViewFeature;
WebView webView = findViewById(R.id.my_webview);
// Before you use a modern API, first check if it is supported.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
// If the check passes, it is safe to call the API.
WebSettingsCompat.setForceDark(webView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
} else {
// Optionally, provide a fallback for older WebView versions.
}
此模式有助于确保应用的稳健性。由于功能检查首先运行,因此如果该功能不可用,应用不会崩溃。
WebViewFeature#isFeatureSupported() 检查的性能开销可以忽略不计。