使用 Jetpack Webkit 簡化 WebView 實作

本指南說明 Jetpack Webkit 程式庫的優點、運作方式,以及如何在專案中實作。

總覽

WebView 是 Android 開發作業中不可或缺的一環,但由於不同 Android OS 版本的功能不一致,因此有時難以管理。每個 Android 作業系統版本都提供一組固定的 WebView API。Android 的發布速度比 WebView 慢,因此 Android API 可能無法涵蓋所有可用的 WebView 功能。這會導致功能推出速度變慢,測試成本也會增加。

Jetpack Webkit 可做為相容性層,並利用使用者裝置上最新的 WebView APK,解決這些問題。此外,這個程式庫還提供專屬的全新現代化 API。

為什麼要使用 Jetpack Webkit?

除了提供跨版本相容性,Jetpack Webkit 也提供新式 API,可簡化開發作業並提升應用程式功能:

瞭解元件

如要有效使用 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 (Android 平台的 OS 版本固定)。這樣一來,即使應用程式安裝在搭載舊版 OS (例如 Android 10) 的裝置上,仍可使用最新的 WebView 功能。舉例來說,WebViewCompat.getWebViewRenderProcess() 的運作方式與 Framework API 類似,但也可以在 Android 10 之前的作業系統版本上呼叫。

如果架構和 Jetpack Webkit 都有某個 API,建議您選擇 Jetpack Webkit 版本。這有助於確保各種裝置的行為和相容性一致。

Jetpack Webkit 和 APK 互動

Jetpack Webkit 中的 API 分為兩部分實作:

  • 靜態 Jetpack Webkit:靜態 Jetpack Webkit 程式庫包含少數負責實作 API 的程式碼。

  • WebView APK:WebView APK 包含大部分的程式碼。

您的應用程式會呼叫 Jetpack Webkit API,然後呼叫 WebView APK。

雖然您可以控管應用程式中的 Jetpack Webkit 版本,但無法控管使用者裝置上的 WebView APK 更新。一般來說,大多數使用者都會安裝最新版本的 WebView APK,但您的應用程式仍須謹慎,不要呼叫特定版本的 WebView APK 不支援的 API。

Jetpack Webkit 也會抽象化,省去手動檢查 WebView 版本的需要。如要判斷某項功能是否可用,請檢查其功能常數。例如 WebViewFeature.WEB_AUTHENTICATION

如何搭配運作

Jetpack Webkit 可彌平靜態 Framework API 與頻繁更新的 WebView APK 之間的鴻溝。使用 Jetpack Webkit API 和功能偵測模式時,程式庫會檢查使用者裝置上安裝的 WebView APK 是否支援該功能。這樣就不必檢查 Android OS (架構) 版本。

如果 WebView APK 的版本夠新,程式庫就會叫用這項功能。 如果沒有,系統會回報該功能無法使用,避免應用程式當機,並讓您妥善處理這種情況。

比較 Jetpack Webkit 和 Framework 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 提供的靜態輔助方法,例如 WebViewCompatWebSettingsCompat。您會將現有的 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.ktsbuild.gradle 檔案中加入下列依附元件,即可新增 Jetpack Webkit:

Groovy

dependencies {
    implementation "androidx.webkit:webkit:1.14.0"
}

Kotlin

dependencies {
    implementation("androidx.webkit:webkit:1.14.0")
}

Jetpack Webkit 包含精簡的包裝函式,因此對應用程式大小的影響極小。

步驟 2:採用功能偵測模式

為避免在叫用無法使用的 API 時發生當機情形,請使用功能檢查。建議您在每次呼叫 API 時都進行功能檢查,並考慮在 API 無法使用時採用備援邏輯。

建議您採用下列模式來使用新版 WebView API:

import android.webkit.WebView
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature

// In your Kotlin code where you configure your WebView
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.
}

這個模式有助於確保應用程式穩定運作。由於系統會先執行功能檢查,因此如果功能無法使用,應用程式就不會當機。WebViewFeature#isFeatureSupported() 檢查的效能負擔微不足道。