Mit WebView können Sie eine Webanwendung oder eine Webseite als Teil einer
Client-App bereitstellen. Die Klasse WebView ist eine Erweiterung der Android-Klasse View
, mit der Sie Webseiten als Teil des Layouts Ihrer Aktivität anzeigen können. Sie enthält nicht die Funktionen eines vollständig entwickelten Webbrowsers, z. B. Navigationssteuerelemente oder eine Adressleiste. Standardmäßig zeigt WebView nur eine Webseite an.
Mit WebView können Sie in Ihrer App Informationen bereitstellen, die möglicherweise aktualisiert werden müssen, z. B. eine Endnutzervereinbarung oder eine Bedienungsanleitung. In Ihrer Android-App,
können Sie ein Activity erstellen, das ein
WebView enthält, und damit Ihr online gehostetes Dokument anzeigen.
WebView kann auch hilfreich sein, wenn Ihre App Daten für den Nutzer bereitstellt, für deren Abruf eine Internetverbindung erforderlich ist, z. B. E-Mails. In diesem Fall ist es möglicherweise einfacher, ein WebView in Ihrer Android-App zu erstellen, das eine Webseite mit allen Nutzerdaten anzeigt, als eine Netzwerkanfrage auszuführen, die Daten zu parsen und sie in einem Android-Layout zu rendern. Stattdessen können Sie eine Webseite entwerfen, die auf Android-Geräte zugeschnitten ist, und dann ein WebView in Ihrer Android-App implementieren, das die Webseite lädt.
In diesem Dokument wird beschrieben, wie Sie WebView verwenden, JavaScript von Ihrer Webseite an clientseitigen Code in Ihrer Android-App binden, die Seitennavigation verarbeiten und Fenster verwalten.WebView
WebView in früheren Android-Versionen verwenden
Wenn Sie neuere WebView Funktionen sicher auf dem Gerät verwenden möchten, auf dem Ihre App
ausgeführt wird, fügen Sie die AndroidX 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 so Ihrer build.gradle-Datei hinzu:
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
Groovy
dependencies { implementation ("androidx.webkit:webkit:1.8.0") }
Weitere Informationen finden Sie im Beispiel WebViewauf GitHub.
WebView zu Ihrer App hinzufügen
Wenn Sie Ihrer App ein WebView hinzufügen möchten, können Sie das Element <WebView> in das
Layout Ihrer Aktivität einfügen oder das gesamte Activity-Fenster in
onCreate() als WebView festlegen.
WebView im Layout der Aktivität hinzufügen
Wenn Sie Ihrer App im Layout ein WebView hinzufügen möchten, fügen Sie der XML-Datei des Layouts Ihrer Aktivität den folgenden Code hinzu:
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
Verwenden Sie loadUrl(), um eine Webseite in der WebView zu laden, 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 ähnliche Logik wie im folgenden Beispiel:
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. Um Internetzugriff zu erhalten, fordern Sie die
INTERNET Berechtigung in Ihrer Manifestdatei an, wie im folgenden
Beispiel gezeigt:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
Sie können WebView so anpassen:
- Aktivieren Sie die Unterstützung für den Vollbildmodus mit
WebChromeClient. Diese Klasse wird auch aufgerufen, wenn einWebViewdie Berechtigung benötigt, die Benutzeroberfläche der Host-App zu ändern, z. B. zum Erstellen oder Schließen von Fenstern oder zum Senden von JavaScript-Dialogfeldern an den Nutzer. Weitere Informationen zum Debuggen in diesem Kontext finden Sie unter Web-Apps debuggen. - Verarbeiten Sie Ereignisse, 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. - Aktivieren Sie JavaScript, indem Sie
WebSettingsändern. - Verwenden Sie JavaScript, um auf Android-Framework-Objekte zuzugreifen, die Sie in ein
WebVieweingefügt haben.
JavaScript in WebView verwenden
Wenn die Webseite, die Sie in WebView laden möchten, JavaScript verwendet, müssen Sie JavaScript für 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 WebView standardmäßig deaktiviert. Sie können es über die WebSettings aktivieren, die an WebView angehängt sind. 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 weiterer Einstellungen, die nützlich sein können. Wenn Sie beispielsweise eine Webanwendung entwickeln, die speziell für die WebView in Ihrer Android-App entwickelt wurde, 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 WebView in Ihrer Android-App entwickelt wurde, können Sie Schnittstellen zwischen Ihrem JavaScript-Code und clientseitigem 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, und einen Schnittstellennamen, mit dem Ihr JavaScript auf die
Klasse zugreifen kann.
Weitere Informationen zur Kommunikation zwischen JavaScript und nativem Code, einschließlich modernerer und sichererer 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 kann die Webseite mit der Klasse WebAppInterface eine
Toast-Nachricht erstellen, indem sie die Methode showToast() verwendet.
Sie können diese Klasse mit addJavascriptInterface() an das JavaScript binden, das in 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 WebView ausgeführt wird. An diesem Punkt hat Ihre Webanwendung Zugriff auf die Klasse WebAppInterface. Hier ist beispielsweise HTML und JavaScript, das eine Toast-Nachricht mit der neuen Schnittstelle erstellt, 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 Schnittstelle Android muss nicht von JavaScript initialisiert werden. WebView stellt sie automatisch für Ihre Webseite zur Verfügung. Wenn ein Nutzer also auf die Schaltfläche tippt, ruft die showAndroidToast() Funktion mit der Android Schnittstelle die WebAppInterface.showToast() Methode auf.
Seitennavigation verarbeiten
Wenn der Nutzer auf einen Link auf einer Webseite in WebView tippt, startet Android standardmäßig eine App, die URLs verarbeitet. Normalerweise wird der Standardwebbrowser geöffnet und die Ziel-URL geladen. Sie können dieses Verhalten jedoch für WebView überschreiben, sodass Links in WebView geöffnet werden. Dann kann der Nutzer in der Webseitenchronik, die von WebView verwaltet wird, vorwärts und rückwärts navigieren.
Wenn Sie Links öffnen möchten, auf die der Nutzer tippt, stellen Sie mit setWebViewClient() einen WebViewClient für WebView
bereit. Alle Links, auf die der Nutzer tippt, werden in WebView geladen. Wenn Sie mehr Kontrolle darüber haben möchten, wo ein angeklickter Link geladen wird, erstellen Sie Ihre
eigene WebViewClient, die die shouldOverrideUrlLoading()
Methode ü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 eine Übereinstimmung gefunden wird, gibt die Methode „false“ zurück und überschreibt das Laden der URL nicht. WebView lädt die URL wie gewohnt.
Wenn der URL-Host nicht übereinstimmt, wird ein Intent erstellt, um die
Standard-Activity für die Verarbeitung von URLs zu starten, die zum Standardweb
browser des Nutzers aufgelöst wird.
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, ruft
WebView sie nur für gültige URLs auf.
So ruft WebView beispielsweise die Methode shouldOverrideUrlLoading() für Links wie diesen nicht 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 wie im vorherigen Beispiel einen einfachen String in einem Link zu verwenden, können Sie ein benutzerdefiniertes Schema wie das folgende verwenden:
<a href="example-app:showProfile">Show Profile</a>
Sie können diese URL dann so in der Methode shouldOverrideUrlLoading() 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 API shouldOverrideUrlLoading() ist hauptsächlich für das Starten von Intents für bestimmte URLs vorgesehen. Wenn Sie sie implementieren, geben Sie für URLs, die von WebView verarbeitet werden, false zurück. 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.
Webseitenchronik durchgehen
Wenn WebView das Laden von URLs überschreibt, wird automatisch eine Chronik der besuchten Webseiten erstellt. Mit goBack() und goForward() können Sie in der
Chronik vorwärts und rückwärts navigieren.
Im folgenden Beispiel wird gezeigt, wie Ihre Activity die Zurück-Schaltfläche des Geräts verwenden kann, um rückwärts zu navigieren:
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 AndroidX 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 eine Webseitenchronik vorhanden ist, die der
Nutzer besuchen kann. Ebenso können Sie mit canGoForward() prüfen, ob
eine Vorwärtschronik vorhanden ist. Wenn Sie diese Prüfung nicht durchführen, tun goBack() und goForward() nichts, nachdem der Nutzer das Ende der Chronik erreicht hat.
Änderungen der Gerätekonfiguration verarbeiten
Während der Laufzeit treten Änderungen des Aktivitätsstatus auf, wenn sich die Konfiguration eines Geräts ändert, z. B. wenn Nutzer das Gerät drehen oder einen Eingabemethoden-Editor (Input Method Editor, IME) schließen. Diese Änderungen führen dazu, dass die Aktivität eines WebView-Objekts zerstört und eine neue Aktivität erstellt wird. Dadurch wird auch ein neues WebView-Objekt erstellt, das die URL des zerstörten Objekts lädt. Wenn Sie das Standardverhalten Ihrer Aktivität ändern möchten, können Sie in Ihrem Manifest ändern, wie sie orientation-Änderungen verarbeitet. Weitere Informationen zum Verarbeiten von Konfigurationsänderungen während der Laufzeit finden Sie unter Umgang mit Konfigurationsänderungen.
Fenster verwalten
Standardmäßig werden Anfragen zum Öffnen neuer Fenster ignoriert. Das gilt unabhängig davon, ob sie von JavaScript oder vom Zielattribut in einem Link geöffnet werden. Sie können WebChromeClient anpassen, um ein eigenes Verhalten für das Öffnen mehrerer Fenster zu definieren.
Um die Sicherheit Ihrer App zu erhöhen, sollten Sie verhindern, dass Pop-ups und neue Fenster geöffnet werden. Die sicherste Möglichkeit, dieses Verhalten zu implementieren, besteht darin, "true" an
setSupportMultipleWindows() zu übergeben, die Methode
onCreateWindow(), von der setSupportMultipleWindows() abhängt, aber nicht zu überschreiben.
Diese Logik verhindert, dass Seiten geladen werden, die in ihren Links target="_blank" verwenden, um
geladen zu werden.