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:
- In Android Studio, fai clic con il tasto destro del mouse sull'app > src > principale e scegli Nuovo > Google Cloud.
- Assegna alla cartella il nome "asset".
- 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. - Ripeti il passaggio precedente per creare un file vuoto per
stylesheet.css
. - 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:
Scarica
Android_symbol_green_RGB.png
sul tuo computer locale.Rinomina il file come
android_robot.png
.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.
.Per completare l'app, svolgi i seguenti passaggi:
Registra i gestori e configura
AssetLoader
aggiungendo il seguente codice al metodoonCreate()
: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));
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 sutext/html
.encoding
: non viene utilizzato quandobaseUrl
è un URL HTTP(S), quindi può essere impostato sunull
.historyUrl
: il valore è impostato sullo stesso valore dibaseUrl
.
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 edata:
URL sono considerati origini opache, il che significa che non possono sfruttare potenti API web comefetch()
oXMLHttpRequest
loadData()
utilizza internamentedata:
URL, quindi ti invitiamo a usareWebViewAssetLoader
oloadDataWithBaseURL()
.- Sebbene
WebSettings.setAllowFileAccessFromFileURLs()
eWebSettings.setAllowUniversalAccessFromFileURLs()
può risolvere i problemi con gli URL difile://
, consigliamo di non impostare atrue
perché così facendo rende la tua app vulnerabile agli attacchi exploit. Ti consigliamo di impostarle esplicitamente sufalse
a tutti i livelli API per la massima sicurezza. - Per gli stessi motivi, sconsigliamo di
file://android_assets/
efile://android_res/
URL.AssetsHandler
eResourcesHandler
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 utilizzaMIXED_CONTENT_COMPATIBILITY_MODE
oMIXED_CONTENT_NEVER_ALLOW
, in base alle necessità.