Utilizza WebView per fornire un'applicazione web o una pagina web come parte di un'
app client. La classe WebView è un'estensione della classe View
di Android che ti consente di visualizzare le pagine web come parte del layout dell'attività. Non include le funzionalità di un browser web completamente sviluppato, come i controlli di navigazione o una barra degli indirizzi. Per impostazione predefinita, WebView mostra solo una pagina web.
WebView può aiutarti a fornire informazioni nella tua app che potresti dover aggiornare, ad esempio un contratto con l'utente finale o una guida per l'utente. All'interno dell'app per Android,
puoi creare un Activity che contiene un
WebView, quindi utilizzarlo per visualizzare il documento ospitato online.
WebView può essere utile anche quando l'app fornisce all'utente dati che richiedono una connessione a internet per essere recuperati, ad esempio le email. In questo caso, potrebbe essere più facile creare un WebView nell'app per Android che mostri una pagina web con tutti i dati utente, anziché eseguire una richiesta di rete, quindi analizzare i dati e visualizzarli in un layout Android. In alternativa, puoi progettare una pagina web personalizzata per i dispositivi con Android e poi implementare un WebView nell'app per Android che carichi la pagina web.
Questo documento descrive come iniziare a utilizzare WebView, come associare il codice JavaScript della pagina web al codice lato client nell'app per Android, come gestire la navigazione nelle pagine e come gestire le finestre quando utilizzi WebView.
Utilizzare WebView nelle versioni precedenti di Android
Per utilizzare in sicurezza le funzionalità più recenti di WebView sul dispositivo su cui è in esecuzione l'app, aggiungi la libreria Jetpack Webkit. Si tratta di una libreria statica che puoi aggiungere alla tua applicazione per utilizzare le API android.webkit non disponibili per le versioni precedenti della piattaforma.
Aggiungila al file build.gradle nel seguente modo:
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.8.0") }
Alla moda
dependencies { implementation ("androidx.webkit:webkit:1.8.0") }
Per maggiori dettagli, consulta l'esempio WebView su GitHub.
Aggiungere un WebView all'app
Per aggiungere un WebView all'app, puoi includere l'elemento <WebView> nel tuo
layout dell'attività o impostare l'intera finestra Activity come WebView in
onCreate.
Aggiungere un WebView nel layout dell'attività
Per aggiungere un WebView all'app nel layout, aggiungi il seguente codice al file XML del layout dell'attività:
<WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" />
Per caricare una pagina web in WebView, utilizza loadUrl, come mostrato nel
l'esempio seguente:
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");
Aggiungere un WebView in onCreate()
Per aggiungere un WebView all'app nel metodo onCreate() di un'attività, utilizza una logica simile alla seguente:
Kotlin
val myWebView = WebView(activityContext) setContentView(myWebView)
Java
WebView myWebView = new WebView(activityContext); setContentView(myWebView);
Poi carica la pagina:
Kotlin
myWebView.loadUrl("http://www.example.com")
Java
myWebView.loadUrl("https://www.example.com");
Oppure carica l'URL da una stringa HTML:
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");
La tua app deve avere accesso a internet. Per ottenere l'accesso a internet, richiedi l'
INTERNET autorizzazione nel file manifest, come mostrato nell'esempio seguente:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
Puoi personalizzare WebView in uno dei seguenti modi:
- Abilitando il supporto dello schermo intero utilizzando
WebChromeClient. Questa classe viene chiamata anche quando unWebViewha bisogno dell'autorizzazione per modificare l'UI dell'app host, ad esempio per creare o chiudere finestre o inviare finestre di dialogo JavaScript all'utente. Per scoprire di più sul debug in questo contesto, leggi Eseguire il debug delle app web. - Gestendo gli eventi che influiscono sul rendering dei contenuti, ad esempio gli errori durante l'invio di moduli
o la navigazione utilizzando
WebViewClient. Puoi utilizzare questa sottoclasse anche per intercettare il caricamento degli URL. - Abilitando JavaScript modificando
WebSettings. - Utilizzando JavaScript per accedere agli oggetti del framework Android che hai inserito in un
WebView.
Utilizzare JavaScript in WebView
Se la pagina web che vuoi caricare in WebView utilizza JavaScript, devi abilitare JavaScript per WebView. Dopo aver abilitato JavaScript, puoi creare interfacce tra il codice dell'app e il codice JavaScript.
Abilitare JavaScript
JavaScript è disattivato in un WebView per impostazione predefinita. Puoi attivarlo tramite WebSettings collegato a WebView. Recupera WebSettings con
getSettings, quindi attiva JavaScript con
setJavaScriptEnabled.
Vedi l'esempio di seguito:
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 fornisce l'accesso a una serie di altre impostazioni che potrebbero essere utili. Ad esempio, se stai sviluppando un'applicazione web progettata specificamente per WebView nella tua app per Android, puoi definire una stringa user agent personalizzata con setUserAgentString, quindi eseguire una query sullo user agent personalizzato nella pagina web per verificare che il client che richiede la pagina web sia la tua app per Android.
Associare il codice JavaScript al codice Android
Quando sviluppi un'applicazione web progettata specificamente per WebView nella tua app per Android, puoi creare interfacce tra il codice JavaScript e il codice Android lato client. Ad esempio, il codice JavaScript può chiamare un metodo in
nel codice Android per visualizzare un Dialog, anziché utilizzare la funzione
alert() di JavaScript.
Per associare una nuova interfaccia tra il codice JavaScript e il codice Android, chiama
addJavascriptInterface, passandogli un'istanza di classe da associare a
JavaScript e un nome di interfaccia che JavaScript può chiamare per accedere alla
classe.
Per scoprire di più sulla comunicazione tra JavaScript e codice nativo, incluse le API più moderne e sicure, vedi Accedere alle API native con JSBridge.
Ad esempio, puoi includere la seguente classe nella tua app Android:
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 questo esempio, la classe WebAppInterface consente alla pagina web di creare un
Toast messaggio, utilizzando il metodo showToast().
Puoi associare questa classe al codice JavaScript in esecuzione in WebView con addJavascriptInterface(), come mostrato nell'esempio seguente:
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");
Viene creata un'interfaccia chiamata Android per il codice JavaScript in esecuzione in WebView. A questo punto, l'applicazione web ha accesso alla classe WebAppInterface. Ad esempio, ecco alcuni codici HTML e JavaScript che creano un messaggio toast utilizzando la nuova interfaccia quando l'utente tocca un pulsante:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } </script>
Non è necessario inizializzare l'interfaccia Android da JavaScript. WebView la rende disponibile automaticamente per la pagina web. Pertanto, quando un utente
tocca il pulsante, la showAndroidToast() funzione utilizza l'interfaccia Android
per chiamare il metodo WebAppInterface.showToast().
Gestire la navigazione nelle pagine
Quando l'utente tocca un link da una pagina web in WebView, per impostazione predefinita Android avvia un'app che gestisce gli URL. In genere, il browser web predefinito si apre e carica l'URL di destinazione. Tuttavia, puoi sostituire questo comportamento per WebView in modo che i link si aprano all'interno di WebView. A questo punto, l'utente può navigare avanti e indietro nella cronologia delle pagine web gestita da WebView.
Per aprire i link toccati dall'utente, fornisci un WebViewClient per WebView
utilizzando setWebViewClient. Tutti i link toccati dall'utente vengono caricati in WebView. Se vuoi avere un maggiore controllo sul caricamento di un link su cui è stato fatto clic, crea il tuo
proprio WebViewClient che esegue l'override del shouldOverrideUrlLoading
metodo. L'esempio seguente presuppone che MyWebViewClient sia una classe interna di Activity.
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; } }
Poi crea un'istanza di questo nuovo WebViewClient per il WebView:
Kotlin
val myWebView: WebView = findViewById(R.id.webview) myWebView.webViewClient = MyWebViewClient()
Java
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
Ora, quando l'utente tocca un link, il sistema chiama il metodo shouldOverrideUrlLoading, che verifica se l'host dell'URL corrisponde a un dominio specifico, come definito nell'esempio precedente. Se corrisponde, il metodo restituisce false e non esegue l'override del caricamento dell'URL. Consente a WebView di caricare l'URL come di consueto.
Se l'host dell'URL non corrisponde, viene creato un Intent per avviare l'
attività Activity predefinita per la gestione degli URL, che si risolve nel browser web
predefinito dell'utente.
Gestire gli URL personalizzati
WebView applica limitazioni quando richiede risorse e risolve i link che utilizzano uno schema URL personalizzato. Ad esempio, se implementi callback come
shouldOverrideUrlLoading o shouldInterceptRequest, allora
WebView li richiama solo per gli URL validi.
Ad esempio, WebView potrebbe non chiamare il metodo shouldOverrideUrlLoading per link come il seguente:
<a href="showProfile">Show Profile</a>
Gli URL non validi, come quello mostrato nell'esempio precedente, vengono gestiti in modo incoerente in WebView, pertanto ti consigliamo di utilizzare un URL ben formato.
Puoi utilizzare uno schema personalizzato o un URL HTTPS per un dominio controllato dalla tua organizzazione.
Anziché utilizzare una semplice stringa in un link, come nell'esempio precedente, puoi utilizzare uno schema personalizzato come il seguente:
<a href="example-app:showProfile">Show Profile</a>
Puoi quindi gestire questo URL nel metodo shouldOverrideUrlLoading nel seguente modo:
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; }
L'API shouldOverrideUrlLoading è destinata principalmente all'avvio di intent per URL specifici. Quando la implementi, assicurati di restituire false per gli URL gestiti da WebView. Tuttavia, non sei limitato all'avvio di intent. Puoi sostituire l'avvio di intent con qualsiasi comportamento personalizzato negli esempi di codice precedenti.
Navigare nella cronologia delle pagine web
Quando WebView esegue l'override del caricamento dell'URL, accumula automaticamente una cronologia delle pagine web visitate. Puoi navigare avanti e indietro nella
cronologia con goBack e goForward.
Ad esempio, il seguente codice mostra come il tuo Activity può utilizzare il pulsante Indietro
del dispositivo per navigare all'indietro:
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); }
Se la tua app utilizza Jetpack AppCompat 1.6.0 o versioni successive, puoi semplificare ulteriormente lo snippet precedente:
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(); } }
Il metodo canGoBack restituisce true se l'utente può visitare la cronologia delle pagine web per. Allo stesso modo, puoi utilizzare canGoForward per verificare se
esiste una cronologia in avanti. Se non esegui questo controllo, dopo che l'utente raggiunge la fine della cronologia, goBack e goForward non fanno nulla.
Per conservare la cronologia di navigazione durante la ricreazione dell'attività o il recupero del processo in background
, utilizza saveState per serializzare la cronologia di navigazione di WebView
in un Bundle e restoreState per ripristinarla.
Per indicazioni su come gestire in sicurezza i limiti di dimensione dello stato salvato ed evitare
TransactionTooLargeException, vedi Gestire in modo efficiente lo stato di WebView.
Gestire le modifiche alla configurazione del dispositivo
Durante l'esecuzione, le modifiche allo stato dell'attività si verificano quando cambia la configurazione di un dispositivo, ad esempio quando gli utenti ruotano il dispositivo o chiudono un editor del metodo di input (IME). Queste modifiche causano la distruzione dell'attività di un oggetto WebView e la creazione di una nuova attività, che crea anche un nuovo oggetto WebView che carica l'URL dell'oggetto distrutto. Puoi utilizzare saveState all'interno
onSaveInstanceState() e restoreState al momento della ricreazione per ripristinare
il contesto di navigazione dell'utente. Per le strategie per gestire in sicurezza le dimensioni dello stato,
vedi Gestire in modo efficiente lo stato di WebView.
Per modificare il comportamento predefinito dell'attività, puoi cambiare la modalità di gestione delle modifiche orientation nel manifest. Per scoprire di più sulla gestione delle
modifiche alla configurazione durante l'esecuzione, leggi Gestire le modifiche alla configurazione.
Gestire le finestre
Per impostazione predefinita, le richieste di apertura di nuove finestre vengono ignorate. Questo vale sia per le finestre aperte da JavaScript sia per l'attributo target in un link. Puoi personalizzare WebChromeClient per fornire un comportamento personalizzato per l'apertura di più finestre.
Per proteggere meglio l'app, è consigliabile impedire l'apertura di popup e nuove finestre. Il modo più sicuro per implementare questo comportamento è passare "true" a
setSupportMultipleWindows senza eseguire l'override del
onCreateWindow metodo, da cui setSupportMultipleWindows() dipende.
Questa logica impedisce il caricamento di qualsiasi pagina che utilizzi target="_blank" nei link da.