In-App-Inhalte laden

Sie können webbasierte Inhalte wie HTML, JavaScript und CSS, damit Ihre App diese statisch kompiliert, statt sie statisch zu kompilieren als über das Internet abzurufen.

In-App-Inhalte erfordern keinen Internetzugang und verbrauchen keine Bandbreite des Nutzers. Wenn der Inhalt speziell für WebView bestimmt ist, d. h. ist von der Kommunikation mit einer nativen App abhängig. So können Nutzer nicht versehentlich laden Sie sie in einem Webbrowser.

In-App-Inhalte haben jedoch auch einige Nachteile. Webbasierte Inhalte aktualisieren erfordert die Lieferung eines neuen App-Updates und es ist möglich, dass die App nicht zwischen den Inhalten einer Website und dem Inhalt der App auf Ihrem Gerät, Nutzer haben veraltete App-Versionen.

WebViewAssetLoader

WebViewAssetLoader ist ein eine flexible und leistungsstarke Methode, In-App-Inhalte WebView-Objekt. Diese Klasse unterstützt die Folgendes:

  • Laden von Inhalten mit einer HTTP(S)-URL für Kompatibilität mit same-origin-URLs .
  • Laden von Unterressourcen wie JavaScript, CSS, Bildern und iFrames

Nimm WebViewAssetLoader in deine Hauptaktivitätsdatei auf. Im Folgenden finden Sie Beispiel für das Laden einfacher Webinhalte aus dem Asset-Ordner:

Kotlin

private class LocalContentWebViewClient(private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() {
    @RequiresApi(21)
    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(request.url)
    }

    // To support API < 21.
    override fun shouldInterceptRequest(
        view: WebView,
        url: String
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(Uri.parse(url))
    }
}

Java

private static class LocalContentWebViewClient extends WebViewClientCompat {

    private final WebViewAssetLoader mAssetLoader;

    LocalContentWebViewClient(WebViewAssetLoader assetLoader) {
        mAssetLoader = assetLoader;
    }

    @Override
    @RequiresApi(21)
    public WebResourceResponse shouldInterceptRequest(WebView view,
                                     WebResourceRequest request) {
        return mAssetLoader.shouldInterceptRequest(request.getUrl());
    }

    @Override
    @SuppressWarnings("deprecation") // To support API < 21.
    public WebResourceResponse shouldInterceptRequest(WebView view,
                                     String url) {
        return mAssetLoader.shouldInterceptRequest(Uri.parse(url));
    }
}

Ihre Anwendung muss eine WebViewAssetLoader-Instanz entsprechend ihren Anforderungen konfigurieren. Die enthält ein Beispiel.

In-App-Assets und -Ressourcen erstellen

WebViewAssetLoader stützt sich auf PathHandler -Instanzen zum Laden von Ressourcen, die einem bestimmten Ressourcenpfad entsprechen. Obwohl Sie können Sie diese Schnittstelle implementieren, um nach Bedarf Ressourcen abzurufen. WebKit-Bibliothekspakete AssetsPathHandler und ResourcesPathHandler zum Laden von Android-Assets bzw. -Ressourcen.

Erstellen Sie zuerst Assets und Ressourcen für Ihre App. Im Allgemeinen gilt Folgendes:

  • Textdateien wie HTML, JavaScript und CSS gehören zu Assets.
  • Bilder und andere Binärdateien gehören zu Ressourcen.

So fügen Sie einem Projekt textbasierte Webdateien hinzu:

  1. Klicke in Android Studio mit der rechten Maustaste auf die App > src > Hauptordner und wählen Sie Neu > Verzeichnis. <ph type="x-smartling-placeholder">
    </ph> Ein Bild, auf dem die Menüs zum Erstellen von Einträgen in Android Studio zu sehen sind <ph type="x-smartling-placeholder">
    </ph> Abbildung 1: Erstellen Sie einen Asset-Ordner für Ihr Projekt arbeiten.
  2. Nennen Sie den Ordner „Assets“. <ph type="x-smartling-placeholder">
    </ph> Ein Bild, auf dem der Asset-Ordner zu sehen ist <ph type="x-smartling-placeholder">
    </ph> Abbildung 2: Geben Sie dem Asset-Ordner einen Namen.
  3. Klicken Sie mit der rechten Maustaste auf den Ordner assets und dann auf Neu > Datei: Geben Sie index.html ein und drücken Sie die Eingabetaste oder Eingabetaste. <ph type="x-smartling-placeholder">
  4. Wiederholen Sie den vorherigen Schritt, um eine leere Datei für stylesheet.css
  5. Füllen Sie die erstellten leeren Dateien mit dem Inhalt in den nächsten beiden Code aus. Proben.
```html
<!-- index.html content -->

<html>
  <head>
    <!-- Tip: Use relative URLs when referring to other in-app content to give
              your app code the flexibility to change the scheme or domain as
              necessary. -->
    <link rel="stylesheet" href="/assets/stylesheet.css">
  </head>
  <body>
    <p>This file is loaded from in-app content.</p>
    <p><img src="/res/drawable/android_robot.png" alt="Android robot" width="100"></p>
  </body>
</html>
```

```css
<!-- stylesheet.css content -->

body {
  background-color: lightblue;
}
```

So fügen Sie Ihrem Projekt eine bildbasierte Webdatei hinzu:

  1. Laden Sie die Android_symbol_green_RGB.png auf Ihren lokalen Computer übertragen.

  2. Benennen Sie die Datei in android_robot.png um.

  3. Verschieben Sie die Datei manuell in das main/res/drawable-Verzeichnis Ihres Projekts auf auf Ihrer Festplatte.

Abbildung 4 zeigt das Bild, das Sie hinzugefügt haben, und den Text aus den vorherigen Codebeispielen die in einer App gerendert werden.

<ph type="x-smartling-placeholder">
</ph> Ein Bild, das die gerenderte App-Ausgabe zeigt <ph type="x-smartling-placeholder">
</ph> Abbildung 4: In-App-HTML- und -Bilddatei die in einer App gerendert werden.

So vervollständigen Sie die Anwendung:

  1. Registrieren Sie die Handler und konfigurieren Sie die AssetLoader, indem Sie den Parameter folgenden Code für die Methode onCreate():

    Kotlin

    val assetLoader = WebViewAssetLoader.Builder()
                           .addPathHandler("/assets/", AssetsPathHandler(this))
                           .addPathHandler("/res/", ResourcesPathHandler(this))
                           .build()
    webView.webViewClient = LocalContentWebViewClient(assetLoader)
    

    Java

    final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
             .addPathHandler("/assets/", new WebViewAssetLoader.AssetsPathHandler(this))
             .addPathHandler("/res/", new WebViewAssetLoader.ResourcesPathHandler(this))
             .build();
    mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
    
  2. Laden Sie den Inhalt, indem Sie der Methode onCreate() den folgenden Code hinzufügen:

    Kotlin

    webView.loadUrl("https://appassets.androidplatform.net/assets/index.html")
    

    Java

    mWebView.loadUrl("https://appassets.androidplatform.net/assets/index.html");
    

In-App-Inhalte mit Ressourcen von deiner Website kombinieren

Ihre App muss möglicherweise eine Mischung aus In-App-Inhalten und Inhalten aus dem z. B. eine mit dem CSS Ihrer Website gestaltete HTML-Seite in der App. WebViewAssetLoader unterstützt diesen Anwendungsfall. Wenn keiner der registrierten PathHandler-Instanzen können eine Ressource für den angegebenen Pfad finden, WebView fällt wieder zum Laden von Inhalten aus dem Internet. Wenn Sie In-App-Inhalte mit Ressourcen von Ihrer Website, reservieren Sie Verzeichnispfade wie /assets/ oder /resources/ für In-App-Ressourcen. Vermeiden Sie es, Ressourcen aus Ihrem Website an diesen Standorten.

Kotlin

val assetLoader = WebViewAssetLoader.Builder()
                        .setDomain("example.com") // Replace this with your website's domain.
                        .addPathHandler("/assets/", AssetsPathHandler(this))
                        .build()

webView.webViewClient = LocalContentWebViewClient(assetLoader)
val inAppHtmlUrl = "https://example.com/assets/index.html"
webView.loadUrl(inAppHtmlUrl)
val websiteUrl = "https://example.com/website/data.json"

// JavaScript code to fetch() content from the same origin.
val jsCode = "fetch('$websiteUrl')" +
        ".then(resp => resp.json())" +
        ".then(data => console.log(data));"

webView.evaluateJavascript(jsCode, null)

Java

final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
           .setDomain("example.com") // Replace this with your website's domain.
           .addPathHandler("/assets/", new AssetsPathHandler(this))
           .build();

mWebView.setWebViewClient(new LocalContentWebViewClient(assetLoader));
String inAppHtmlUrl = "https://example.com/assets/index.html";
mWebView.loadUrl(inAppHtmlUrl);
String websiteUrl = "https://example.com/website/data.json";

// JavaScript code to fetch() content from the same origin.
String jsCode = "fetch('" + websiteUrl + "')" +
      ".then(resp => resp.json())" +
      ".then(data => console.log(data));";

mWebView.evaluateJavascript(jsCode, null);

WebView-Demo ansehen auf GitHub finden Sie ein Beispiel für eine In-App-HTML-Seite, die webgehostete JSON-Daten abruft.

LoadDataWithBaseURL (DatenmitBasis-URL laden)

Wenn Ihre App nur eine HTML-Seite laden und nicht abfangen muss Unterressourcen verwenden, sollten Sie loadDataWithBaseURL(), für die keine App-Assets erforderlich sind. Sie können es wie im folgenden Code gezeigt verwenden: Beispiel:

Kotlin

val html = "<html><body><p>Hello world</p></body></html>"
val baseUrl = "https://example.com/"

webView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl)

Java

String html = "<html><body><p>Hello world</p></body></html>";
String baseUrl = "https://example.com/";

mWebView.loadDataWithBaseURL(baseUrl, html, "text/html", null, baseUrl);

Wählen Sie Argumentwerte mit Bedacht aus. Hier einige Tipps:

  • baseUrl: Dies ist die URL, unter der Ihr HTML-Inhalt geladen wird. Dies muss ein HTTP(S)-URL
  • data: Dies ist der HTML-Inhalt, der als String angezeigt werden soll.
  • mimeType: Muss normalerweise auf text/html gesetzt sein.
  • encoding: Wird nicht verwendet, wenn baseUrl eine HTTP(S)-URL ist. Daher kann sie verwendet werden. auf null festgelegt.
  • historyUrl: Wird auf denselben Wert wie baseUrl festgelegt.

Wir empfehlen dringend, für baseUrl eine HTTP(S)-URL zu verwenden, da dies Ihre App der Richtlinie für denselben Ursprung entspricht.

Wenn du kein passendes baseUrl für deine Inhalte findest und lieber loadData(), müssen Sie den Inhalt mit Prozentcodierung oder Base64 Codierung. Wir empfehlen dringend, die Base64-Codierung auszuwählen und Android-APIs für die Codierung zu verwenden. wie im folgenden Codebeispiel gezeigt:

Kotlin

val encodedHtml: String = Base64.encodeToString(html.toByteArray(), Base64.NO_PADDING)

webView.loadData(encodedHtml, mimeType, "base64")

Java

String encodedHtml = Base64.encodeToString(html.getBytes(), Base64.NO_PADDING);

mWebView.loadData(encodedHtml, mimeType, "base64");

Was du vermeiden solltest

Es gibt mehrere andere Möglichkeiten, In-App-Inhalte zu laden, wir empfehlen jedoch dringend, gegen sie:

  • file:// URLs und data: URLs gelten als intransparente Ursprünge. Das bedeutet, dass sie leistungsstarke Web-APIs wie fetch() oder XMLHttpRequest loadData() verwendet intern data: URLs, daher empfehlen wir die Verwendung von WebViewAssetLoader oder loadDataWithBaseURL().
  • Obwohl WebSettings.setAllowFileAccessFromFileURLs() und WebSettings.setAllowUniversalAccessFromFileURLs() die Probleme mit file://-URLs umgehen können, empfehlen wir, an true, da Ihre App dann anfällig für dateibasierte Exploits. Wir empfehlen, sie auf allen API-Ebenen explizit auf false festzulegen für bestmögliche Sicherheit.
  • Aus denselben Gründen raten wir davon ab, file://android_assets/ und file://android_res/ URLs. AssetsHandler und ResourcesHandler Klassen als „Drop-in-Ersatz“ dienen.
  • Vermeiden Sie MIXED_CONTENT_ALWAYS_ALLOW Diese Einstellung ist in der Regel nicht erforderlich und beeinträchtigt die Sicherheit Ihrer App. Wir empfehlen, Ihre In-App-Inhalte über dasselbe Schema zu laden: HTTP oder HTTPS – als Ressourcen Ihrer Website und zur Verwendung MIXED_CONTENT_COMPATIBILITY_MODE oder MIXED_CONTENT_NEVER_ALLOW, .