Mit WebView können Sie eine Webanwendung oder Webseite als Teil einer Client-App bereitstellen. Die Klasse WebView ist eine Erweiterung der Android-Klasse View, mit der Sie Webseiten als Teil Ihres Aktivitätslayouts anzeigen können. Sie enthält nicht die Funktionen eines vollständig entwickelten Webbrowsers, wie z. B. Navigationssteuerelemente oder eine Adressleiste. Standardmäßig wird auf WebView nur eine Webseite angezeigt.
WebView kann Ihnen dabei helfen, Informationen in Ihrer App bereitzustellen, die Sie möglicherweise aktualisieren müssen, z. B. eine Nutzungsvereinbarung oder ein Nutzerhandbuch. In Ihrer Android-App können Sie eine Activity erstellen, die eine WebView enthält, und damit Ihr online gehostetes Dokument anzeigen.
WebView kann auch hilfreich sein, wenn Ihre App dem Nutzer Daten zur Verfügung stellt, für die eine Internetverbindung erforderlich ist, z. B. E-Mails. In diesem Fall ist es möglicherweise einfacher, eine WebView in Ihrer Android-App zu erstellen, die eine Webseite mit allen Nutzerdaten anzeigt, anstatt eine Netzwerkanfrage auszuführen, die Daten zu parsen und sie in einem Android-Layout zu rendern. Stattdessen kannst du eine Webseite entwerfen, die auf Android-Geräte zugeschnitten ist, und dann eine WebView in deiner Android-App implementieren, die die Webseite lädt.
In diesem Dokument wird beschrieben, wie Sie mit WebView beginnen, wie Sie JavaScript von Ihrer Webseite an clientseitigen Code in Ihrer Android-App binden, wie Sie die Seitennavigation handhaben und wie Sie Fenster verwalten, wenn Sie WebView verwenden.
WebView in früheren Android-Versionen verwenden
Wenn Sie neuere WebView-Funktionen auf dem Gerät, auf dem Ihre App ausgeführt wird, sicher verwenden möchten, fügen Sie die Jetpack Webkit-Bibliothek hinzu. Dies ist eine statische Bibliothek, die Sie Ihrer Anwendung hinzufügen können, um android.webkit-APIs zu verwenden, die für frühere Plattformversionen nicht verfügbar sind.
Fügen Sie sie der Datei build.gradle so hinzu:
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
Groovy
dependencies { implementation ("androidx.webkit:webkit:1.8.0") }
Weitere Informationen finden Sie im WebView-Beispiel auf GitHub.
WebView zur App hinzufügen
Wenn du deiner App ein WebView hinzufügen möchtest, kannst du das <WebView>-Element in dein Aktivitätslayout einfügen oder das gesamte Activity-Fenster in onCreate als WebView festlegen.
WebView im Aktivitätslayout hinzufügen
Wenn Sie Ihrer App im Layout ein WebView hinzufügen möchten, fügen Sie der XML-Layoutdatei Ihrer Aktivität den folgenden Code hinzu:
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
Wenn Sie eine Webseite in der WebView laden möchten, verwenden Sie loadUrl, wie im folgenden Beispiel gezeigt:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.loadUrl("http://www.example.com")
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.loadUrl("http://www.example.com");
WebView in „onCreate()“ hinzufügen
Wenn Sie Ihrer App stattdessen in der Methode onCreate() einer Aktivität ein WebView hinzufügen möchten, verwenden Sie eine Logik wie die folgende:
Kotlin
val myWebView = WebView(activityContext) setContentView(myWebView)
Java
WebView myWebView = new WebView(activityContext); setContentView(myWebView);
Laden Sie dann die Seite:
Kotlin
myWebView.loadUrl("http://www.example.com")
Java
myWebView.loadUrl("https://www.example.com");
Oder laden Sie die URL aus einem HTML-String:
Kotlin
// Create an unencoded HTML string, then convert the unencoded HTML string into // bytes. Encode it with base64 and load the data. val unencodedHtml = "<html><body>'%23' is the percent code for ‘#‘ </body></html>"; val encodedHtml = Base64.encodeToString(unencodedHtml.toByteArray(), Base64.NO_PADDING) myWebView.loadData(encodedHtml, "text/html", "base64")
Java
// Create an unencoded HTML string, then convert the unencoded HTML string into // bytes. Encode it with base64 and load the data. String unencodedHtml = "<html><body>'%23' is the percent code for ‘#‘ </body></html>"; String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(), Base64.NO_PADDING); myWebView.loadData(encodedHtml, "text/html", "base64");
Ihre App muss Zugriff auf das Internet haben. Wenn Sie Internetzugriff benötigen, fordern Sie in Ihrer Manifestdatei die Berechtigung INTERNET an, wie im folgenden Beispiel gezeigt:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
Sie können Ihre WebView so anpassen:
- Vollbildunterstützung mit
WebChromeClientaktivieren. Diese Klasse wird auch aufgerufen, wenn einWebViewdie Berechtigung zum Ändern der Benutzeroberfläche der Host-App benötigt, z. B. zum Erstellen oder Schließen von Fenstern oder zum Senden von JavaScript-Dialogfeldern an den Nutzer. Weitere Informationen zum Debugging in diesem Kontext finden Sie unter Web-Apps debuggen. - Verarbeitung von Ereignissen, die sich auf das Rendern von Inhalten auswirken, z. B. Fehler beim Senden von Formularen oder bei der Navigation mit
WebViewClient. Sie können diese Unterklasse auch verwenden, um das Laden von URLs abzufangen. - JavaScript durch Ändern von
WebSettingsaktivieren. - Verwendung von JavaScript für den Zugriff auf Android-Framework-Objekte, die Sie in ein
WebVieweingefügt haben.
JavaScript in WebView verwenden
Wenn die Webseite, die Sie in Ihrer WebView laden möchten, JavaScript verwendet, müssen Sie JavaScript für Ihre WebView aktivieren. Nachdem Sie JavaScript aktiviert haben, können Sie Schnittstellen zwischen Ihrem App-Code und Ihrem JavaScript-Code erstellen.
JavaScript aktivieren
JavaScript ist in einer WebView standardmäßig deaktiviert. Sie können sie über die WebSettings aktivieren, die an Ihre WebView angehängt ist. Rufen Sie WebSettings mit getSettings ab und aktivieren Sie dann JavaScript mit setJavaScriptEnabled.
Siehe folgendes Beispiel:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.settings.javaScriptEnabled = true
Java
WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);
WebSettings bietet Zugriff auf eine Vielzahl anderer Einstellungen, die für Sie nützlich sein könnten. Wenn Sie beispielsweise eine Webanwendung entwickeln, die speziell für die WebView in Ihrer Android-App konzipiert ist, können Sie mit setUserAgentString einen benutzerdefinierten User-Agent-String definieren und dann den benutzerdefinierten User-Agent auf Ihrer Webseite abfragen, um zu prüfen, ob der Client, der Ihre Webseite anfordert, Ihre Android-App ist.
JavaScript-Code an Android-Code binden
Wenn Sie eine Webanwendung entwickeln, die speziell für die WebView in Ihrer Android-App konzipiert ist, können Sie Schnittstellen zwischen Ihrem JavaScript-Code und dem clientseitigen Android-Code erstellen. Ihr JavaScript-Code kann beispielsweise eine Methode in Ihrem Android-Code aufrufen, um ein Dialog anzuzeigen, anstatt die JavaScript-Funktion alert() zu verwenden.
Wenn Sie eine neue Schnittstelle zwischen Ihrem JavaScript- und Android-Code binden möchten, rufen Sie addJavascriptInterface auf und übergeben Sie eine Klasseninstanz, die an Ihr JavaScript gebunden werden soll, sowie einen Schnittstellennamen, den Ihr JavaScript aufrufen kann, um auf die Klasse zuzugreifen.
Weitere Informationen zur Kommunikation zwischen JavaScript und nativem Code, einschließlich modernerer und sicherer APIs, finden Sie unter Mit JSBridge auf native APIs zugreifen.
Sie können beispielsweise die folgende Klasse in Ihre Android-App einfügen:
Kotlin
/** Instantiate the interface and set the context. */ class WebAppInterface(private val mContext: Context) { /** Show a toast from the web page. */ @JavascriptInterface fun showToast(toast: String) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show() } }
Java
public class WebAppInterface { Context mContext; /** Instantiate the interface and set the context. */ WebAppInterface(Context c) { mContext = c; } /** Show a toast from the web page. */ @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } }
In diesem Beispiel ermöglicht die Klasse WebAppInterface der Webseite, mit der Methode showToast() eine Toast-Nachricht zu erstellen.
Sie können diese Klasse mit addJavascriptInterface() an das JavaScript binden, das in Ihrer WebView ausgeführt wird, wie im folgenden Beispiel gezeigt:
Kotlin
val webView: WebView = findViewById(R.id.webview) webView.addJavascriptInterface(WebAppInterface(this), "Android")
Java
WebView webView = (WebView) findViewById(R.id.webview); webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Dadurch wird eine Schnittstelle namens Android für JavaScript erstellt, das in der WebView ausgeführt wird. An diesem Punkt hat Ihre Webanwendung Zugriff auf die Klasse WebAppInterface. Hier ist ein Beispiel für HTML und JavaScript, mit dem eine Toast-Nachricht über die neue Oberfläche erstellt wird, wenn der Nutzer auf eine Schaltfläche tippt:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>
Die Android-Schnittstelle muss nicht über JavaScript initialisiert werden. Die WebView stellt sie automatisch auf Ihrer Webseite zur Verfügung. Wenn ein Nutzer auf die Schaltfläche tippt, verwendet die Funktion showAndroidToast() die Schnittstelle Android, um die Methode WebAppInterface.showToast() aufzurufen.
Seitennavigation verarbeiten
Wenn der Nutzer auf einer Webseite in deiner WebView auf einen Link tippt, startet Android standardmäßig eine App, die URLs verarbeitet. Normalerweise wird der Standard-Webbrowser geöffnet und die Ziel-URL geladen. Sie können dieses Verhalten jedoch für Ihre WebView überschreiben, sodass Links in Ihrer WebView geöffnet werden. Anschließend können Sie den Nutzer im Verlauf der Webseiten, die von Ihrer WebView verwaltet werden, vor- und zurücknavigieren lassen.
Wenn Sie Links öffnen möchten, auf die der Nutzer tippt, geben Sie mit setWebViewClient einen WebViewClient für Ihren WebView an. Alle Links, auf die der Nutzer tippt, werden in Ihrer WebView geladen. Wenn Sie mehr Kontrolle darüber haben möchten, wo ein angeklickter Link geladen wird, erstellen Sie einen eigenen WebViewClient, der die Methode shouldOverrideUrlLoading überschreibt. Im folgenden Beispiel wird davon ausgegangen, dass MyWebViewClient eine innere Klasse von Activity ist.
Kotlin
private class MyWebViewClient : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { if (Uri.parse(url).host == "www.example.com") { // This is your website, so don't override. Let your WebView load // the page. return false } // Otherwise, the link isn't for a page on your site, so launch another // Activity that handles URLs. Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply { startActivity(this) } return true } }
Java
private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { if ("www.example.com".equals(request.getUrl().getHost())) { // This is your website, so don't override. Let your WebView load the // page. return false; } // Otherwise, the link isn't for a page on your site, so launch another // Activity that handles URLs. Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); startActivity(intent); return true; } }
Erstellen Sie dann eine Instanz dieses neuen WebViewClient für die WebView:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.webViewClient = MyWebViewClient()
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
Wenn der Nutzer jetzt auf einen Link tippt, ruft das System die Methode shouldOverrideUrlLoading auf, die prüft, ob der URL-Host mit einer bestimmten Domain übereinstimmt, wie im vorherigen Beispiel definiert. Wenn sie übereinstimmt, gibt die Methode „false“ zurück und überschreibt das Laden der URL nicht. Die URL wird wie gewohnt im WebView geladen.
Wenn der URL-Host nicht übereinstimmt, wird ein Intent erstellt, um den Standard-Activity für die Verarbeitung von URLs zu starten, der auf den Standard-Webbrowser des Nutzers verweist.
Benutzerdefinierte URLs verarbeiten
WebView wendet Einschränkungen an, wenn Ressourcen angefordert und Links aufgelöst werden, die ein benutzerdefiniertes URL-Schema verwenden. Wenn Sie beispielsweise Callbacks wie shouldOverrideUrlLoading oder shouldInterceptRequest implementieren, werden sie von WebView nur für gültige URLs aufgerufen.
Beispielsweise ruft WebView die Methode shouldOverrideUrlLoading möglicherweise nicht für Links wie diesen auf:
<a href="showProfile">Show Profile</a>
Ungültige URLs wie die im vorherigen Beispiel werden in WebView inkonsistent verarbeitet. Wir empfehlen daher, stattdessen eine wohlgeformte URL zu verwenden.
Sie können ein benutzerdefiniertes Schema oder eine HTTPS-URL für eine Domain verwenden, die von Ihrer Organisation kontrolliert wird.
Anstatt einen einfachen String in einem Link zu verwenden, wie im vorherigen Beispiel, können Sie ein benutzerdefiniertes Schema wie das folgende verwenden:
<a href="example-app:showProfile">Show Profile</a>
Diese URL können Sie dann in Ihrer shouldOverrideUrlLoading-Methode so verarbeiten:
Kotlin
// The URL scheme must be non-hierarchical, meaning no trailing slashes. const val APP_SCHEME = "example-app:" override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return if (url?.startsWith(APP_SCHEME) == true) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length), "UTF-8") respondToData(urlData) true } else { false } }
Java
// The URL scheme must be non-hierarchical, meaning no trailing slashes. private static final String APP_SCHEME = "example-app:"; @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith(APP_SCHEME)) { urlData = URLDecoder.decode(url.substring(APP_SCHEME.length()), "UTF-8"); respondToData(urlData); return true; } return false; }
Die shouldOverrideUrlLoading API ist in erster Linie für das Starten von Intents für bestimmte URLs vorgesehen. Achte bei der Implementierung darauf, dass für URLs, die von der WebView verarbeitet werden, false zurückgegeben wird. Sie sind jedoch nicht auf das Starten von Intents beschränkt. Sie können das Starten von Intents in den vorherigen Codebeispielen durch ein beliebiges benutzerdefiniertes Verhalten ersetzen.
Webseitenverlauf aufrufen
Wenn die WebView das Laden von URLs überschreibt, wird automatisch ein Verlauf der besuchten Webseiten erstellt. Mit goBack und goForward können Sie im Verlauf vor- und zurückgehen.
Im folgenden Beispiel wird gezeigt, wie Sie mit dem Button „Zurück“ des Geräts in Ihrer Activity zurückgehen können:
Kotlin
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { // Check whether the key event is the Back button and if there's history. if (keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack()) { myWebView.goBack() return true } // If it isn't the Back button or there isn't web page history, bubble up to // the default system behavior. Probably exit the activity. return super.onKeyDown(keyCode, event) }
Java
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { // Check whether the key event is the Back button and if there's history. if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) { myWebView.goBack(); return true; } // If it isn't the Back button or there's no web page history, bubble up to // the default system behavior. Probably exit the activity. return super.onKeyDown(keyCode, event); }
Wenn Ihre App Jetpack AppCompat 1.6.0 oder höher verwendet, können Sie das vorherige Snippet noch weiter vereinfachen:
Kotlin
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack() } }
Java
onBackPressedDispatcher.addCallback { // Check whether there's history. if (myWebView.canGoBack()) { myWebView.goBack(); } }
Die Methode canGoBack gibt „true“ zurück, wenn ein Webseitenverlauf vorhanden ist, den der Nutzer aufrufen kann. Ebenso können Sie mit canGoForward prüfen, ob ein Vorwärtsverlauf vorhanden ist. Wenn Sie diese Prüfung nicht durchführen, haben goBack und goForward keine Auswirkungen, nachdem der Nutzer das Ende des Verlaufs erreicht hat.
Wenn Sie den Navigationsverlauf über die Neuerstellung von Aktivitäten oder die Wiederherstellung von Hintergrundprozessen hinweg beibehalten möchten, verwenden Sie saveState, um den Navigationsverlauf der WebView in ein Bundle zu serialisieren, und restoreState, um ihn wiederherzustellen.
Eine Anleitung zum sicheren Verwalten der Größenbeschränkungen für gespeicherte Zustände und zum Vermeiden von TransactionTooLargeException finden Sie unter WebView-Zustand effizient verwalten.
Änderungen der Gerätekonfiguration verarbeiten
Während der Laufzeit ändert sich der Aktivitätsstatus, wenn sich die Konfiguration eines Geräts ändert, z. B. wenn Nutzer das Gerät drehen oder einen Eingabemethoden-Editor (IME) schließen. Diese Änderungen führen dazu, dass die Aktivität eines WebView-Objekts gelöscht und eine neue Aktivität erstellt wird. Dadurch wird auch ein neues WebView-Objekt erstellt, das die URL des gelöschten Objekts lädt. Sie können saveState in onSaveInstanceState() und restoreState bei der Neuerstellung verwenden, um den Navigationskontext des Nutzers wiederherzustellen. Strategien zur sicheren Verwaltung der Statusgröße finden Sie unter WebView-Status effizient verwalten.
Wenn Sie das Standardverhalten Ihrer Aktivität ändern möchten, können Sie in Ihrem Manifest festlegen, wie orientation-Änderungen verarbeitet werden. Weitere Informationen zum Umgang mit Konfigurationsänderungen während der Laufzeit finden Sie unter Konfigurationsänderungen verarbeiten.
Fenster verwalten
Anfragen zum Öffnen neuer Fenster werden standardmäßig ignoriert. Das gilt unabhängig davon, ob sie über JavaScript oder das Zielattribut in einem Link geöffnet werden. Sie können WebChromeClient anpassen, um ein eigenes Verhalten für das Öffnen mehrerer Fenster festzulegen.
Um die Sicherheit Ihrer App zu erhöhen, sollten Sie verhindern, dass Pop-ups und neue Fenster geöffnet werden. Die sicherste Methode, dieses Verhalten zu implementieren, besteht darin, "true" an setSupportMultipleWindows zu übergeben, aber die Methode onCreateWindow, von der setSupportMultipleWindows() abhängt, nicht zu überschreiben.
Diese Logik verhindert, dass Seiten geladen werden, die target="_blank" in ihren Links verwenden.
Arbeitsspeicher und Leistung verwalten
Da WebView auf einer Chromium-basierten Engine mit separaten Prozessen und nativem Code ausgeführt wird, ist die grundlegende Arbeitsspeichernutzung höher als bei Standard-Android-Ansichten.
Die Wiederverwendung von WebView-Instanzen und deren ordnungsgemäße Zerstörung sind für die Aufrechterhaltung einer stabilen App unerlässlich.
Weitere Informationen zum Diagnostizieren und Optimieren des Speicherbedarfs Ihrer App bei der Verwendung von Webinhalten finden Sie unter WebView-Speicher verwalten und diagnostizieren.