Gérer les objets WebView

Android fournit plusieurs API pour vous aider à gérer WebView qui affichent du contenu Web dans votre application.

Cette page explique comment utiliser ces API pour travailler avec WebView. les objets plus efficacement, ce qui améliore la stabilité et la sécurité de votre application.

API de la version

À partir d'Android 7.0 (niveau d'API 24), les utilisateurs peuvent choisir parmi plusieurs des packages différents pour afficher du contenu Web dans un objet WebView. Le fichier AndroidX.webkit la bibliothèque contient getCurrentWebViewPackage() qui permet d'extraire des informations relatives au package qui affiche le contenu le contenu de votre application. Cette méthode est utile lors de l'analyse des erreurs qui ne se produisent Lorsque votre application tente d'afficher du contenu Web à l'aide de l'attribut l'implémentation de WebView.

Pour utiliser cette méthode, ajoutez la logique illustrée dans l'extrait de code suivant:

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);
<ph type="x-smartling-placeholder">

Service de navigation sécurisée Google

Pour offrir à vos utilisateurs une navigation plus sécurisée, WebView vérifient les URL à l'aide de Navigation sécurisée Google, qui permet à votre application d'afficher un avertissement aux utilisateurs lorsqu'ils tentent d'accéder à un potentiellement dangereux.

Bien que la valeur par défaut de EnableSafeBrowsing soit "true", sont les cas dans lesquels vous souhaiterez peut-être n'activer la navigation sécurisée le désactiver. Android 8.0 (niveau d'API 26) et versions ultérieures sont compatibles avec l'utilisation de setSafeBrowsingEnabled() pour activer/désactiver la navigation sécurisée pour un objet WebView individuel.

Si vous souhaitez que la navigation sécurisée soit désactivée pour tous les objets WebView des vérifications, ajoutez l'élément <meta-data> suivant au fichier manifeste:

<ph type="x-smartling-placeholder">
<manifest>
    <application>
        <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
                   android:value="false" />
        ...
    </application>
</manifest>
<ph type="x-smartling-placeholder">

Définir des actions programmatiques

Lorsqu'une instance de WebView tente de charger une page qui est classé par Google comme une menace connue, le WebView par défaut affiche un interstitiel qui avertit les utilisateurs de la menace connue. Cet écran donne aux utilisateurs de charger quand même l'URL ou de revenir à une page en toute sécurité.

Si vous ciblez Android 8.1 (niveau d'API 27) ou une version ultérieure, vous pouvez définir de manière automatisée la réponse de votre application à une menace connue différentes manières:

  • Vous pouvez contrôler si votre application signale les menaces connues à Safe Navigation.
  • Vous pouvez faire en sorte que votre application effectue automatiquement une action particulière, par exemple à la sécurité. Chaque fois qu'il rencontre une URL considérée comme une menace connue.
<ph type="x-smartling-placeholder">

Les extraits de code suivants montrent comment indiquer aux instances de votre application WebView pour toujours revenir en sécurité après avoir rencontré un menace:

MyWebActivity.java

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

MyWebViewClient.java

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

Pour les applications ciblant Android 6.0 (niveau d'API 23) ou version ultérieure, l'API Geolocation n'est compatible qu'avec les origines sécurisées, telles que HTTPS. Toute requête envoyée au L'API Geolocation sur les origines non sécurisées est automatiquement refusée sans appeler la méthode onGeolocationPermissionsShowPrompt() correspondante.

Désactiver la collecte de métriques

WebView peut importer des données de diagnostic anonymes sur à Google lorsque l'utilisateur donne son consentement. Les données sont collectées pour chaque application pour chaque application qui instancie un WebView. Vous pouvez désactiver en créant la balise suivante dans le fichier manifeste Élément <application>:

<manifest>
    <application>
    ...
    <meta-data android:name="android.webkit.WebView.MetricsOptOut"
               android:value="true" />
    </application>
</manifest>

Les données ne sont importées depuis une application que si l'utilisateur y consent et l'application ne se désinscrit pas. En savoir plus sur la désactivation des données de diagnostic pour les rapports, consultez la section Confidentialité des utilisateurs dans WebView rapports.

API Endpoint Handling

L'API Endpoint Handling gère les cas où le processus de rendu pour un WebView disparaît, soit parce que le système arrête le moteur de rendu pour récupérer la mémoire nécessaire ou parce que le processus du moteur de rendu plante. Cette API vous permet permettent à votre application de continuer à s'exécuter, même si le processus du moteur de rendu disparaît.

<ph type="x-smartling-placeholder">

Si un moteur de rendu plante pendant le chargement d'une page Web spécifique, charger à nouveau la même page peut entraîner un nouvel objet WebView présentent le même comportement de plantage de rendu.

L'extrait de code suivant montre comment utiliser cette API dans 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

Lorsque WebView objets interviennent en mode multiprocessus, vous bénéficiez d'une certaine flexibilité dans la façon dont votre application gère de mémoire insuffisante. Vous pouvez utiliser l'API Renderer Importance, présentée dans Android 8.0, pour définir une règle de priorité pour le moteur de rendu attribué à une WebView. Vous pouvez par exemple vouloir que la partie principale de votre application pour qu'elle continue de s'exécuter lorsqu'un moteur de rendu WebView objets sont supprimés. Vous pouvez le faire, par exemple, si vous s'attendre à ne pas afficher l'objet WebView pendant un long moment afin que peut récupérer la mémoire utilisée par le moteur de rendu.

L'extrait de code suivant montre comment attribuer une priorité au moteur de rendu associé aux objets WebView de votre application:

Kotlin

val myWebView: WebView = ...
myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)

Java

WebView myWebView;
myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);

Dans cet extrait de code particulier, la priorité du moteur de rendu est la même que : est lié, c'est-à-dire la priorité par défaut de l'application. true réduit la priorité du moteur de rendu RENDERER_PRIORITY_WAIVED Lorsque l'objet WebView associé n'est plus visible. Dans d'autres l'argument true indique que votre application ne se soucie pas le système maintient en vie le processus du moteur de rendu. En fait, ce niveau de priorité inférieur augmente la probabilité que le processus du moteur de rendu soit arrêté pour cause de mémoire insuffisante situations différentes.

<ph type="x-smartling-placeholder">

Pour en savoir plus sur la façon dont le système gère les situations de mémoire insuffisante, consultez Processus et application cycle de vie.