Android mette a disposizione diverse API per aiutarti a gestire
WebView
oggetti che mostrano contenuti web nella tua app.
In questa pagina viene descritto come utilizzare queste API per lavorare con WebView
oggetti in modo più efficace, migliorando stabilità e sicurezza dell'app.
API Version
A partire da Android 7.0 (livello API 24), gli utenti possono scegliere tra diverse
diversi pacchetti per la visualizzazione di contenuti web in un oggetto WebView
.
L'app AndroidX.webkit
include
getCurrentWebViewPackage()
per recuperare le informazioni relative al pacchetto che mostra
contenuti nella tua app. Questo metodo è utile per analizzare errori che si verificano solo
quando la tua app tenta di visualizzare contenuti web utilizzando il metodo
implementazione di WebView
.
Per utilizzare questo metodo, aggiungi la logica mostrata nel seguente snippet di codice:
Kotlin
val webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext) Log.d("MY_APP_TAG", "WebView version: ${webViewPackageInfo.versionName}")
Java
PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext); Log.d("MY_APP_TAG", "WebView version: " + webViewPackageInfo.versionName);
Servizio Google Navigazione sicura
Per offrire ai tuoi utenti un'esperienza di navigazione più sicura, WebView
per verificare gli URL utilizzando
Google Navigazione sicura,
che consente alla tua app di mostrare un avviso agli utenti quando tentano di accedere a un
sito web potenzialmente non sicuro.
Sebbene il valore predefinito di EnableSafeBrowsing
sia true,
potresti voler attivare Navigazione sicura solo in modo condizionale
disabilitarlo. Android 8.0 (livello API 26) e versioni successive supporta l'utilizzo di
setSafeBrowsingEnabled()
per attivare/disattivare Navigazione sicura per un singolo oggetto WebView
.
Se vuoi disattivare Navigazione sicura per tutti gli oggetti WebView
controlli, aggiungi il seguente elemento <meta-data>
al
file manifest:
<manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" /> ... </application> </manifest>
Definisci le azioni di pubblicità programmatica
Quando un'istanza di WebView
tenta di caricare una pagina che
classificata da Google come minaccia nota, WebView
per impostazione predefinita
mostra un interstitial che avvisa gli utenti della minaccia nota. Questa schermata fornisce
agli utenti la possibilità di caricare comunque l'URL o di tornare a una pagina precedente
in tutta sicurezza.
Se scegli come target Android 8.1 (livello API 27) o versioni successive, puoi definire in modo programmatico il modo in cui la tua app risponde a una minaccia nota nei seguenti modi:
- Puoi controllare se la tua app segnala minacce note a Safe Navigazione.
- Puoi impostare la tua app in modo che esegua automaticamente una determinata azione, ad esempio come tornare in un luogo sicuro, ogni volta che rileva un URL classificata come minaccia nota.
I seguenti snippet di codice mostrano come indicare alle istanze dell'app
WebView
per tornare sempre in sicurezza dopo aver riscontrato un
minaccia:
Kotlin
private lateinit var superSafeWebView: WebView private var safeBrowsingIsInitialized: Boolean = false // ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) superSafeWebView = WebView(this) superSafeWebView.webViewClient = MyWebViewClient() safeBrowsingIsInitialized = false if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) { WebViewCompat.startSafeBrowsing(this, ValueCallback<Boolean> { success -> safeBrowsingIsInitialized = true if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!") } }) } }
Java
private WebView superSafeWebView; private boolean safeBrowsingIsInitialized; // ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); superSafeWebView = new WebView(this); superSafeWebView.setWebViewClient(new MyWebViewClient()); safeBrowsingIsInitialized = false; if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) { WebViewCompat.startSafeBrowsing(this, new ValueCallback<Boolean>() { @Override public void onReceiveValue(Boolean success) { safeBrowsingIsInitialized = true; if (!success) { Log.e("MY_APP_TAG", "Unable to initialize Safe Browsing!"); } } }); } }
Kotlin
class MyWebViewClient : WebViewClientCompat() { // Automatically go "back to safety" when attempting to load a website that // Google identifies as a known threat. An instance of WebView calls this // method only after Safe Browsing is initialized, so there's no conditional // logic needed here. override fun onSafeBrowsingHit( view: WebView, request: WebResourceRequest, threatType: Int, callback: SafeBrowsingResponseCompat ) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. if (WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY)) { callback.backToSafety(true) Toast.makeText(view.context, "Unsafe web page blocked.", Toast.LENGTH_LONG).show() } } }
Java
public class MyWebViewClient extends WebViewClientCompat { // Automatically go "back to safety" when attempting to load a website that // Google identifies as a known threat. An instance of WebView calls this // method only after Safe Browsing is initialized, so there's no conditional // logic needed here. @Override public void onSafeBrowsingHit(WebView view, WebResourceRequest request, int threatType, SafeBrowsingResponseCompat callback) { // The "true" argument indicates that your app reports incidents like // this one to Safe Browsing. if (WebViewFeature.isFeatureSupported(WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY)) { callback.backToSafety(true); Toast.makeText(view.getContext(), "Unsafe web page blocked.", Toast.LENGTH_LONG).show(); } } }
API HTML5 Geolocation
Per le app che hanno come target Android 6.0 (livello API 23) e versioni successive, l'API Geolocation
è supportato solo su origini sicure, come HTTPS. Qualsiasi richiesta inviata a
L'API Geolocation su origini non sicure viene negata automaticamente senza richiamare
il metodo onGeolocationPermissionsShowPrompt()
corrispondente.
Disattiva la raccolta delle metriche
WebView
può caricare dati diagnostici anonimi su
Google quando l'utente dà il proprio consenso. I dati vengono raccolti per singola app
per ogni app che crea un'istanza per un WebView
. Puoi disattivare questa opzione
creando il seguente tag nel file manifest
<application>
elemento:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" /> </application> </manifest>
I dati vengono caricati da un'app solo se l'utente acconsente e l'app non effettua la disattivazione. Per ulteriori informazioni sulla disattivazione dei dati diagnostici Per i report, consulta Privacy degli utenti in WebView i report.
API Termination handling
L'API Finish handling gestisce i casi in cui il renderer elabora un
WebView
scompare, perché il sistema termina il renderer per recuperare
necessaria o perché il processo del renderer si arresta in modo anomalo. Utilizzando questa API,
consente all'app di continuare a essere eseguita, anche se il processo del renderer non viene più visualizzato.
Se un renderer si arresta in modo anomalo durante il caricamento di una pagina web specifica,
se viene caricata di nuovo la stessa pagina, è possibile che un nuovo oggetto WebView
lo stesso comportamento di arresto anomalo del rendering.
Il seguente snippet di codice illustra come utilizzare questa API in un
Activity
:
Kotlin
inner class MyRendererTrackingWebViewClient : WebViewClient() { private var mWebView: WebView? = null override fun onRenderProcessGone(view: WebView, detail: RenderProcessGoneDetail): Boolean { if (!detail.didCrash()) { // Renderer is killed because the system ran out of memory. The app // can recover gracefully by creating a new WebView instance in the // foreground. Log.e("MY_APP_TAG", ("System killed the WebView rendering process " + "to reclaim memory. Recreating...")) mWebView?.also { webView -> val webViewContainer: ViewGroup = findViewById(R.id.my_web_view_container) webViewContainer.removeView(webView) webView.destroy() mWebView = null } // By this point, the instance variable "mWebView" is guaranteed to // be null, so it's safe to reinitialize it. return true // The app continues executing. } // Renderer crashes because of an internal error, such as a memory // access violation. Log.e("MY_APP_TAG", "The WebView rendering process crashed!") // In this example, the app itself crashes after detecting that the // renderer crashed. If you handle the crash more gracefully and let // your app continue executing, you must destroy the current WebView // instance, specify logic for how the app continues executing, and // return "true" instead. return false } }
Java
public class MyRendererTrackingWebViewClient extends WebViewClient { private WebView mWebView; @Override public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) { if (!detail.didCrash()) { // Renderer is killed because the system ran out of memory. The app // can recover gracefully by creating a new WebView instance in the // foreground. Log.e("MY_APP_TAG", "System killed the WebView rendering process " + "to reclaim memory. Recreating..."); if (mWebView != null) { ViewGroup webViewContainer = (ViewGroup) findViewById(R.id.my_web_view_container); webViewContainer.removeView(mWebView); mWebView.destroy(); mWebView = null; } // By this point, the instance variable "mWebView" is guaranteed to // be null, so it's safe to reinitialize it. return true; // The app continues executing. } // Renderer crashes because of an internal error, such as a memory // access violation. Log.e("MY_APP_TAG", "The WebView rendering process crashed!"); // In this example, the app itself crashes after detecting that the // renderer crashed. If you handle the crash more gracefully and let // your app continue executing, you must destroy the current WebView // instance, specify logic for how the app continues executing, and // return "true" instead. return false; } }
API Renderer Importance
Quando WebView
oggetti
operano
modalità multiprocesso, hai una certa flessibilità nel modo in cui la tua app gestisce
situazioni di esaurimento della memoria. Puoi usare l'API Renderer Importance, introdotta in
Android 8.0, per impostare un criterio di priorità per il renderer assegnato a un determinato renderer
WebView
oggetto. In particolare, potresti volere che la parte principale
di continuare l'esecuzione quando un renderer che visualizza
WebView
oggetti sono terminati. Potresti farlo, ad esempio, se
l'oggetto WebView
non verrà mostrato per molto tempo, in modo che
può recuperare la memoria utilizzata dal renderer.
Il seguente snippet di codice mostra come assegnare una priorità al renderer
processo associato agli oggetti WebView
dell'app:
Kotlin
val myWebView: WebView = ... myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)
Java
WebView myWebView; myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);
In questo particolare snippet, la priorità del renderer è la stessa della
la priorità predefinita per l'app. true
diminuisce la priorità del renderer a
RENDERER_PRIORITY_WAIVED
quando l'oggetto WebView
associato non è più visibile. In altre
parole, un argomento true
indica che alla tua app non è importante se
il sistema mantiene attivo il processo di rendering. Di fatto, questo livello di priorità inferiore
è probabile che il processo del renderer venga interrotto in memoria
in situazioni diverse.
Per scoprire di più su come il sistema gestisce le situazioni in cui la memoria è insufficiente, vedi Processi e app del ciclo di vita.