Carica contenuti in-app

Puoi fornire contenuti basati sul web, ad esempio HTML, JavaScript e CSS, che la tua app può utilizzare, inseriti in modo statico nell'app anziché rispetto al recupero su internet.

I contenuti in-app non richiedono l'accesso a internet né consumano larghezza di banda dell'utente. Se i contenuti sono progettati appositamente per WebView, ovvero dipende dalla comunicazione con un'app nativa, gli utenti non potranno per sbaglio in un browser web.

Tuttavia, i contenuti in-app presentano alcuni svantaggi. Aggiornamento dei contenuti basati sul web richiede la spedizione di un nuovo aggiornamento dell'app ed è possibile che l'app non corrisponda tra i contenuti di un sito web e quelli dell'app sul dispositivo se gli utenti hanno versioni obsolete dell'app.

WebViewAssetLoader

WebViewAssetLoader è un in modo flessibile ed efficiente per caricare contenuti in-app WebView. Questo corso supporta seguenti:

  • Caricamento di contenuti con un URL HTTP(S) per garantire la compatibilità con la stessa origine .
  • Caricamento di risorse secondarie, ad esempio JavaScript, CSS, immagini e iframe.

Includi WebViewAssetLoader nel file delle attività principale. Di seguito è riportato un esempio di caricamento di semplici contenuti web dalla cartella degli asset:

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));
    }
}

L'app deve configurare un'istanza WebViewAssetLoader in base alle sue esigenze. La nella sezione successiva presenta un esempio.

Creare asset e risorse in-app

WebViewAssetLoader si basa su PathHandler per caricare le risorse corrispondenti a un determinato percorso delle risorse. Anche se puoi implementare questa interfaccia per recuperare risorse secondo necessità dalla tua app, Bundle di librerie Webkit AssetsPathHandler e ResourcesPathHandler per caricare le risorse e gli asset Android.

Per iniziare, crea asset e risorse per la tua app. In genere, si applica quanto segue:

  • I file di testo come HTML, JavaScript e CSS appartengono agli asset.
  • Le immagini e altri file binari appartengono alle risorse.

Per aggiungere file web di testo a un progetto, segui questi passaggi:

  1. In Android Studio, fai clic con il tasto destro del mouse sull'app > src > principale e scegli Nuovo > Google Cloud.
    Un&#39;immagine che mostra i menu della directory di creazione di Android Studio
    . Figura 1. Crea una cartella di asset progetto.
  2. Assegna alla cartella il nome "asset".
    Un&#39;immagine che mostra la cartella degli asset
    . Figura 2. Assegna un nome alla cartella degli asset.
  3. Fai clic con il tasto destro del mouse sulla cartella asset, quindi fai clic su Nuovo > . Inserisci index.html e premi il tasto Invio o Tasto Invio.
  4. Ripeti il passaggio precedente per creare un file vuoto per stylesheet.css.
  5. Compila i file vuoti che hai creato con i contenuti nei prossimi due codici i campioni.
```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;
}
```

Per aggiungere al tuo progetto un file web basato su immagini:

  1. Scarica Android_symbol_green_RGB.png sul tuo computer locale.

  2. Rinomina il file come android_robot.png.

  3. Sposta manualmente il file nella directory main/res/drawable del progetto su sul disco rigido.

La figura 4 mostra l'immagine che hai aggiunto e il testo degli esempi di codice precedenti visualizzato in un'app.

Un&#39;immagine che mostra l&#39;output del rendering dell&#39;app
. Figura 4. File HTML e file immagine in-app visualizzato in un'app.
di Gemini Advanced.
.

Per completare l'app, svolgi i seguenti passaggi:

  1. Registra i gestori e configura AssetLoader aggiungendo il seguente codice al metodo 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. Carica i contenuti aggiungendo il seguente codice al metodo onCreate():

    Kotlin

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

    Java

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

Combina i contenuti in-app con le risorse del tuo sito web

La tua app potrebbe dover caricare un mix di contenuti in-app e contenuti dal internet, ad esempio una pagina HTML in-app definita dal CSS del tuo sito web. WebViewAssetLoader supporta questo caso d'uso. Se nessuno degli utenti registrati PathHandler istanze possono trovare una risorsa per il percorso specificato, mentre WebView al caricamento dei contenuti da internet. Se unisci contenuti in-app e risorse dal tuo sito web, prenota i percorsi delle directory, ad esempio /assets/ /resources/, per le risorse in-app. Evita di archiviare risorse dal tuo sito web in quelle località.

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);

Guarda la demo WebView su GitHub per un esempio di pagina HTML in-app che recupera dati JSON ospitati sul web.

caricamentoDatiConURLBase

Quando la tua app deve caricare solo una pagina HTML e non deve intercettare di risorse secondarie, considera l'uso loadDataWithBaseURL(), che non richiedono asset per app. Puoi utilizzarlo come mostrato nel codice seguente esempio:

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);

Scegli con attenzione i valori dell'argomento. Tieni in considerazione:

  • baseUrl: questo è l'URL utilizzato per caricare i tuoi contenuti HTML. Deve essere un URL HTTP(S).
  • data: sono i contenuti HTML che vuoi visualizzare, come stringa.
  • mimeType: generalmente questo valore deve essere impostato su text/html.
  • encoding: non viene utilizzato quando baseUrl è un URL HTTP(S), quindi può essere impostato su null.
  • historyUrl: il valore è impostato sullo stesso valore di baseUrl.

Ti consigliamo vivamente di utilizzare un URL HTTP(S) come baseUrl, in quanto ciò consente Assicurati che la tua app sia conforme alle norme relative alla stessa origine.

Se non riesci a trovare un baseUrl adatto ai tuoi contenuti e preferisci utilizzarlo loadData(), devi codificare i contenuti con codifica percentuale o Base64 di codifica. Ti consigliamo vivamente di scegliere la codifica Base64 e di utilizzare le API Android per la codifica questo in modo programmatico, come mostrato nell'esempio di codice riportato di seguito:

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");

Cose da evitare

Esistono diversi altri modi per caricare i contenuti in-app, ma ti consigliamo vivamente rispetto a questi:

  • file:// URL e data: URL sono considerati origini opache, il che significa che non possono sfruttare potenti API web come fetch() o XMLHttpRequest loadData() utilizza internamente data: URL, quindi ti invitiamo a usare WebViewAssetLoader o loadDataWithBaseURL().
  • Sebbene WebSettings.setAllowFileAccessFromFileURLs() e WebSettings.setAllowUniversalAccessFromFileURLs() può risolvere i problemi con gli URL di file://, consigliamo di non impostare a true perché così facendo rende la tua app vulnerabile agli attacchi exploit. Ti consigliamo di impostarle esplicitamente su false a tutti i livelli API per la massima sicurezza.
  • Per gli stessi motivi, sconsigliamo di file://android_assets/ e file://android_res/ URL. AssetsHandler e ResourcesHandler le classi sono pensate per sostituire i prodotti direttamente dall'utente.
  • Evita di utilizzare MIXED_CONTENT_ALWAYS_ALLOW Questa impostazione in genere non è necessaria e riduce la sicurezza della tua app. Ti consigliamo di caricare i contenuti in-app utilizzando lo stesso schema: HTTP o HTTPS: come risorse del tuo sito web e che utilizza MIXED_CONTENT_COMPATIBILITY_MODE o MIXED_CONTENT_NEVER_ALLOW, in base alle necessità.