WebView-Implementierung mit Jetpack Webkit vereinfachen

In dieser Anleitung werden die Vorteile der Jetpack Webkit-Bibliothek beschrieben. Außerdem wird erläutert, wie sie funktioniert und wie Sie sie in Ihren Projekten implementieren können.

Übersicht

WebViews sind ein wesentlicher Bestandteil der Android-Entwicklung. Aufgrund von Inkonsistenzen bei den Funktionen in verschiedenen Android-Betriebssystemversionen kann ihre Verwaltung jedoch manchmal schwierig sein. Jede Android-Version bietet eine feste Anzahl von WebView APIs. Da Android langsamer als WebView veröffentlicht wird, decken die Android APIs möglicherweise nicht alle verfügbaren WebView-Funktionen ab. Dies führt zu einer langsameren Einführung von Funktionen und höheren Testkosten.

Jetpack Webkit löst diese Probleme, indem es als Kompatibilitätsebene fungiert und das aktuelle WebView APK auf dem Gerät des Nutzers verwendet. Es enthält auch neue und moderne APIs, die ausschließlich in dieser Bibliothek verfügbar sind.

Warum Jetpack Webkit verwenden?

Jetpack Webkit bietet nicht nur Kompatibilität über verschiedene Versionen hinweg, sondern auch neue und moderne APIs, die die Entwicklung vereinfachen und die Funktionalität Ihrer App verbessern können:

  • Moderne Authentifizierung aktivieren: WebView kann moderne Web authentifizierungsstandards wie WebAuthn nahtlos verarbeiten und so Anmeldungen mit Passkeys ermöglichen. Mit der androidx.webkit Bibliothek haben Sie die vollständige Kontrolle über diese Integration mit der WebSettingsCompat.setWebAuthenticationSupport() Methode, mit der Sie den Grad der Unterstützung konfigurieren können, die Ihre App benötigt.

  • Leistung verbessern: Sie können die Leistung von WebView mit APIs wie setBackForwardCacheEnabled optimieren oder die Navigationslatenz mit spekulativen Lade-APIs wie prefetchUrlAsync und prerenderUrlAsync reduzieren. Weitere Informationen finden Sie unter Spekulatives Laden in WebView.

  • Stabilität erhöhen: Sie können angehaltene oder nicht reagierende Renderer-Prozesse wiederherstellen ohne dass die App abstürzt. Weitere Informationen finden Sie unter WebViewRenderProcess#terminate().

  • Granulare Kontrolle über Browserdaten: Mit der Klasse WebStorageCompat können Sie Browserdaten löschen, die von WebView für bestimmte Ursprünge gespeichert wurden.

  • Status- und Speichereffizienz verbessern: Navigationsstatus sicher serialisieren innerhalb des Transaktionsbudgets von 1 MB und vermeiden TransactionTooLargeException Abstürze durch Statusserialisierung mit Größenbeschränkung mit WebViewCompat.saveState(). Weitere Informationen finden Sie unter WebView-Status effizient verwalten.

Komponenten

Damit Sie Jetpack Webkit effektiv nutzen können, müssen Sie die Beziehung zwischen den folgenden Komponenten verstehen:

  • Android System WebView: Dies ist die Chromium-basierte Rendering-Engine, die Google regelmäßig über den Google Play Store aktualisiert, und zwar im gleichen Rhythmus wie Chrome. Sie enthält die neuesten Funktionen und den zugrunde liegenden Implementierungscode für alle WebView APIs.

  • Framework APIs (android.webkit): Diese APIs sind an eine bestimmte Android-Version gebunden. Eine App unter Android 10 kann beispielsweise nur auf die APIs zugreifen, die bei der Veröffentlichung dieser Version verfügbar waren. Sie kann also keine neuen Funktionen verwenden, die in neueren Updates zum WebView APK hinzugefügt wurden. Wenn Sie beispielsweise mit einen nicht reagierenden Renderer verarbeiten möchten WebView#getWebViewRenderProcess(), können Sie diese Methode nur unter Android 10 und höher aufrufen.

  • Jetpack Webkit-Bibliothek (androidx.webkit): Dies ist eine kleine Bibliothek, die in Ihrer Anwendung enthalten ist. Diese Bibliothek fungiert als Brücke, die das WebView APK aufruft, anstatt die in der Android-Plattform definierten APIs aufzurufen, die eine feste Betriebssystemversion haben. So kann eine Anwendung auch dann die neuesten WebView-Funktionen verwenden, wenn sie auf einem Gerät mit einer älteren Betriebssystemversion wie Android 10 installiert ist. For example, WebViewCompat.getWebViewRenderProcess() funktioniert ähnlich wie die Framework API, kann aber auch für alle Betriebssystemversionen vor Android 10 aufgerufen werden.

Wenn eine API sowohl im Framework als auch in Jetpack Webkit verfügbar ist, empfehlen wir Ihnen, die Jetpack Webkit-Version zu verwenden. So sorgen Sie für ein einheitliches Verhalten und Kompatibilität auf einer Vielzahl von Geräten.

Interaktion zwischen Jetpack Webkit und APK

Die APIs in Jetpack Webkit sind in zwei Teile implementiert:

  • Statisches Jetpack Webkit: Die statische Jetpack Webkit-Bibliothek enthält einen kleinen Teil des Codes, der für die Implementierung der API verantwortlich ist.

  • WebView APK: Das WebView APK enthält den größten Teil des Codes.

Ihre App ruft die Jetpack Webkit API auf, die dann das WebView APK aufruft.

Sie können zwar die Jetpack Webkit-Version in Ihrer App steuern, aber nicht die WebView APK-Updates auf den Geräten der Nutzer. Im Allgemeinen haben die meisten Nutzer aktuelle Versionen des WebView APK, aber Ihre App muss trotzdem darauf achten, keine APIs aufzurufen, die von dieser Version des WebView APK nicht unterstützt werden.

Jetpack Webkit macht es auch überflüssig, WebView-Versionen manuell zu prüfen. Um festzustellen, ob eine Funktion verfügbar ist, prüfen Sie die entsprechende Feature-Konstante. Beispiel: WebViewFeature.WEB_AUTHENTICATION.

Zusammenarbeit

Jetpack Webkit schließt die Lücke zwischen der statischen Framework API und dem häufig aktualisierten WebView APK. Wenn Sie die Jetpack Webkit API mit dem Muster zur Funktionserkennung verwenden, prüft die Bibliothek, ob die Funktion vom WebView APK unterstützt wird, das auf dem Gerät des Nutzers installiert ist. So müssen Sie die Android-Betriebssystem-Version (Framework) nicht prüfen.

Wenn das WebView APK eine aktuelle Version hat, ruft die Bibliothek die Funktion auf. Andernfalls wird gemeldet, dass die Funktion nicht verfügbar ist. So wird verhindert, dass Ihre App abstürzt, und Sie können die Situation auf elegante Weise handhaben.

Jetpack Webkit und Framework APIs im Vergleich

In diesem Abschnitt werden Implementierungsmethoden mit und ohne die Jetpack Webkit-Bibliothek verglichen:

Moderne Authentifizierung (WebAuthn) aktivieren

Ohne Jetpack Webkit

Nicht über Framework APIs möglich.

Mit Jetpack Webkit

Verwendet WebViewFeature.WEB_AUTHENTICATION für Kompatibilitätsprüfungen.

if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_AUTHENTICATION)) {
  WebSettingsCompat.setWebAuthenticationSupport(
      webView.settings,
      WebSettingsCompat.WEB_AUTHENTICATION_SUPPORT_FOR_APP
  )
}

Daten für einen Ursprung löschen (sitespezifischer Speicher)

Ohne Jetpack Webkit

Keine direkte API zum Löschen bestimmter Ursprungsdaten. Oft müssen alle Daten gelöscht werden.

Mit Jetpack Webkit

Verwendet Kompatibilitäts-APIs für das präzise Löschen von Daten. Sie haben folgende Möglichkeiten:

WebStorageCompat.getInstance().deleteBrowsingData()

Oder

WebStorageCompat.getInstance().deleteBrowsingDataForSite()

WebView-Version abrufen

Ohne Jetpack Webkit

Verwendet die Standard-Framework-Klasse.

val webViewPackage = WebView.getCurrentWebViewPackage()

Mit Jetpack Webkit

Verwendet die Kompatibilitätsebene für einen sichereren Abruf.

val webViewPackage = WebViewCompat.getCurrentWebViewPackage()

Nicht reagierenden Renderer verarbeiten (Renderer-Client)

Ohne Jetpack Webkit

Verwendet die Standard-Framework-Methode.

webView.setWebViewRenderProcessClient(myClient)

Mit Jetpack Webkit

Verwendet WebViewCompat und eine Funktionsprüfung zum Festlegen des Clients.

if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE)) {
  WebViewCompat.setWebViewRenderProcessClient(webView, myClient)
}

Informationen zum Implementieren von Strategien zur Wiederherstellung nach Abstürzen finden Sie unter Umgang mit der Beendigung von WebView. Details zu den APIs finden Sie in der androidx.webkit Referenzdokumentation.

Gespeicherten Status und Transaktionsgröße verwalten

Mit der API WebViewCompat.saveState können Sie Byte-Limits erzwingen und den Vorwärtsverlauf während der Serialisierung bereinigen. So vermeiden Sie Abstürze aufgrund von TransactionTooLargeException und behalten gleichzeitig den wichtigen Navigationsverlauf bei.

Ohne Jetpack Webkit

Verwendet die Standard-Framework-Methode, die den gesamten Navigationsstack ohne Größenbeschränkungen serialisiert und TransactionTooLargeException auslösen kann, wenn die Nutzlast das Transaktionslimit von 1 MB für Android überschreitet.

webView.saveState(outState)

Mit Jetpack Webkit

Verwendet WebViewCompat, um ein maximales Byte-Limit zu erzwingen oder Vorwärtsnavigationseinträge zu entfernen, um Transaktionsüberläufe zu vermeiden.

WebViewCompat.saveState(webView, outState, maxSizeBytes)

Weitere Informationen finden Sie unter WebView-Status effizient verwalten.

Jetpack Webkit in Ihren Code einbinden

Durch die Verwendung von Jetpack Webkit werden die Funktionen der Standard-WebView-Klasse erweitert, aber die ursprüngliche WebView-Klasse wird nicht vollständig ersetzt.

Sie können die android.webkit.WebView Klasse weiterhin verwenden. Sie können sie Ihren XML-Layouts hinzufügen und eine Referenz zur Instanz in Ihrem Code abrufen. Um auf Standard-Framework-Funktionen zuzugreifen, können Sie weiterhin Methoden direkt für die WebView-Instanz oder das zugehörige Einstellungsobjekt aufrufen.

Für den Zugriff auf moderne Funktionen verwenden Sie die statischen Hilfsmethoden von Jetpack Webkit, z. B. WebViewCompat und WebSettingsCompat. Sie übergeben Ihre vorhandene WebView-Instanz an diese Methoden.

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 implementieren

Gehen Sie so vor, um Jetpack Webkit zu implementieren:

Schritt 1: Abhängigkeit hinzufügen

Fügen Sie in der Datei build.gradle.kts oder build.gradle Ihres Moduls die folgende Abhängigkeit hinzu, um Jetpack Webkit hinzuzufügen:

Cool

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

Kotlin

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

Jetpack Webkit enthält schlanke Wrapper, sodass die Auswirkungen auf die Größe Ihrer Anwendung minimal sind.

Schritt 2: Muster zur Funktionserkennung übernehmen

Verwenden Sie Funktionsprüfungen, um Abstürze zu vermeiden, wenn nicht verfügbare APIs aufgerufen werden. Wir empfehlen, jeden API-Aufruf mit einer Funktionsprüfung zu umgeben und möglicherweise eine Fallback-Logik für den Fall zu berücksichtigen, dass die API nicht verfügbar ist.

Wir empfehlen das folgende Muster für die Verwendung einer modernen 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.
}

Dieses Muster trägt dazu bei, dass die Anwendung robust ist. Da die Funktionsprüfung zuerst ausgeführt wird, stürzt die Anwendung nicht ab, wenn die Funktion nicht verfügbar ist. Der Leistungsaufwand der WebViewFeature#isFeatureSupported() Prüfung ist vernachlässigbar.