Jetpack Webkit で WebView の実装を簡素化する

このガイドでは、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 も提供します。

  • 最新の認証を有効にする: WebView は WebAuthn などの最新のウェブ認証標準をシームレスに処理し、パスキーベースのログインを可能にします。androidx.webkit ライブラリでは、WebSettingsCompat.setWebAuthenticationSupport() メソッドを使用してこの統合を完全に制御できます。このメソッドを使用して、アプリに必要なサポートレベルを構成できます。

  • パフォーマンスの向上: prefetchUrlAsyncprerenderUrlAsyncsetBackForwardCacheEnabled などの API を使用して、アプリのユースケースに合わせて WebView のパフォーマンスを調整します。

  • 安定性の向上: 停止または応答しないレンダラ プロセスをクラッシュせずに復元します。詳細については、WebViewRenderProcess#terminate() をご覧ください。

  • 閲覧データをきめ細かく制御できる: 特定のオリジンについて WebView が保存した閲覧データを削除するには、WebStorageCompat クラスを使用します。

コンポーネントを理解する

Jetpack Webkit を効果的に使用するには、次のコンポーネント間の関係を理解する必要があります。

  • Android システムの WebView: これは、Google が Google Play ストアを通じて Chrome と同じペースで定期的に更新する Chromium ベースのレンダリング エンジンです。最新の機能が含まれており、すべての WebView API の基盤となる実装コードを提供します。

  • フレームワーク API(android.webkit: 特定の Android OS バージョンに固定されている API です。たとえば、Android 10 のアプリは、そのバージョンがリリースされたときに利用可能だった API にのみアクセスできます。そのため、最近のアップデートで WebView APK に追加された新機能を使用できません。たとえば、WebView#getWebViewRenderProcess() で応答しないレンダラを処理するには、Android 10 以降でのみ呼び出すことができます。

  • Jetpack Webkit ライブラリ(androidx.webkit: アプリケーションにバンドルされている小さなライブラリです。このライブラリは、固定の OS バージョンを持つ Android プラットフォームで定義された API を呼び出すのではなく、WebView APK を呼び出すブリッジとして機能します。これにより、Android 10 などの古い OS バージョンを搭載したデバイスにアプリがインストールされている場合でも、アプリは最新の WebView 機能を使用できます。たとえば、WebViewCompat.getWebViewRenderProcess() は Framework API と同様に動作しますが、Android 10 より前のすべての OS バージョンでも呼び出すことができます。

API がフレームワークと Jetpack Webkit の両方で利用可能な場合は、Jetpack Webkit バージョンを選択することをおすすめします。これにより、さまざまなデバイスで一貫した動作と互換性を確保できます。

Jetpack Webkit と APK のインタラクション

Jetpack Webkit の API は、次の 2 つの部分で実装されています。

  • 静的 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 は、静的な 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.kts ファイルまたは build.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() チェックのパフォーマンス オーバーヘッドは無視できます。