WebView-Objekte verwalten

Android bietet mehrere APIs, mit denen Sie die WebView Objekte, die Webinhalte in Ihrer App anzeigen.

Auf dieser Seite wird beschrieben, wie Sie diese APIs für WebView verwenden. -Objekten effektiver zu erstellen und so die Stabilität und Sicherheit Ihrer App zu verbessern.

API-Version

Ab Android 7.0 (API-Level 24) können Nutzer aus verschiedenen verschiedene Pakete zur Anzeige von Webinhalten in einem WebView-Objekt an. Die Methode AndroidX.webkit enthält die getCurrentWebViewPackage() Methode zum Abrufen von Informationen zu dem Paket, das das Web anzeigt Inhalte in Ihrer App. Diese Methode ist nützlich, wenn Fehler analysiert werden, die nur auftreten. wenn Ihre App versucht, Webinhalte mithilfe der Implementierung von WebView.

Um diese Methode zu verwenden, fügen Sie die im folgenden Code-Snippet gezeigte Logik hinzu:

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

Google Safe Browsing-Dienst

Um Ihren Nutzern ein sichereres Surfen zu ermöglichen, WebView -Objekt verifizieren URLs mithilfe von Google Safe Browsing, So wird Nutzern in Ihrer App eine Warnung angezeigt, wenn sie versuchen, potenziell unsichere Website.

Obwohl der Standardwert von EnableSafeBrowsing "true" ist, gibt es kann es sinnvoll sein, Safe Browsing nur bedingt oder deaktivieren. Android 8.0 (API-Level 26) und höher unterstützt die Verwendung von setSafeBrowsingEnabled() um Safe Browsing für ein einzelnes WebView-Objekt ein- oder auszuschalten.

Wenn Sie möchten, dass alle WebView-Objekte Safe Browsing deaktivieren fügt das folgende <meta-data>-Element zum Manifestdatei:

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

Programmatische Aktionen definieren

Wenn eine Instanz von WebView versucht, eine Seite zu laden, von Google als bekannte Bedrohung klassifiziert, WebView zeigt ein Interstitial, das Nutzer vor der bekannten Bedrohung warnt. Auf diesem Bildschirm erhalten Sie die URL trotzdem laden oder zu einer vorherigen Seite zurückkehren, zu schützen.

Wenn Ihre App auf Android 8.1 (API-Level 27) oder höher ausgerichtet ist, können Sie wie Ihre App auf eine bekannte Bedrohung reagiert, Möglichkeiten:

  • Du kannst festlegen, ob deine App bekannte Bedrohungen an Safe meldet Surfen.
  • Sie können festlegen, dass Ihre App automatisch eine bestimmte Aktion ausführt, z. B. jedes Mal, wenn sie auf eine URL stößt, die die als bekannte Bedrohung bezeichnet werden.
<ph type="x-smartling-placeholder">

Die folgenden Code-Snippets zeigen, wie Sie die Instanzen Ihrer App WebView, um nach dem Auftreten eines bekannten Fehlers immer in Sicherheit zu gehen. Bedrohung:

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

HTML5 Geolocation API

Für Apps, die auf Android 6.0 (API-Level 23) und höher ausgerichtet sind: die Geolocation API wird nur für sichere Ursprünge wie HTTPS unterstützt. Jede Anfrage an den Geolocation API bei unsicheren Ursprüngen wird automatisch ohne Aufruf abgelehnt. die entsprechende onGeolocationPermissionsShowPrompt()-Methode.

Erfassung von Messwerten deaktivieren

WebView kann anonyme Diagnosedaten hochladen auf Google, wenn der Nutzer seine Einwilligung erteilt. Die Daten werden pro App erhoben für jede App, die eine WebView instanziiert. Sie können diese Option deaktivieren indem Sie das folgende Tag im Manifest <application>-Element:

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

Daten werden nur dann aus einer App hochgeladen, wenn der Nutzer einwilligt und wird die App nicht deaktiviert. Weitere Informationen zum Deaktivieren der Diagnosedaten siehe Datenschutz in WebView Berichterstellung.

Beendigungsbehandlungs-API

Die Beendigung Handling API kann in Fällen, in denen der Renderer-Prozess für eine WebView verschwindet, weil das System den Renderer beendet, um die oder weil der Renderer-Prozess abstürzt. Durch die Verwendung dieser API die App weiter ausführen lassen, auch wenn der Renderer-Prozess verschwindet.

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

Wenn ein Renderer beim Laden einer bestimmten Webseite abstürzt, beim erneuten Laden derselben Seite kann dazu führen, dass ein neues WebView-Objekt das gleiche Rendering-Absturzverhalten aufweisen.

Das folgende Code-Snippet veranschaulicht, wie diese API innerhalb eines 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;
    }
}

Renderer-Wichtigkeits-API

Wenn WebView Objekte arbeiten in Multiprozessmodus handelt, können Sie bei der Verarbeitung der Anwendung nicht genügend Arbeitsspeicher. Sie können die Renderer Importance API verwenden, die in In Android 8.0 können Sie eine Prioritätsrichtlinie für den Renderer festlegen, der einem bestimmten WebView-Objekt. Insbesondere sollten Sie den Hauptteil Ihres ausgeführt werden soll, wenn ein Renderer, der die WebView Objekte wurden gelöscht. Das ist z. B. dann der Fall, wenn Sie erwarten, dass das WebView-Objekt lange Zeit nicht zu sehen ist, damit das vom Renderer verbrauchten Arbeitsspeicher freigeben.

Das folgende Code-Snippet zeigt, wie dem Renderer eine Priorität zugewiesen wird. Prozess, der mit den WebView-Objekten Ihrer App verknüpft ist:

Kotlin

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

Java

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

In diesem speziellen Snippet hat der Renderer die gleiche Priorität wie an die gebunden ist: die Standardpriorität für die Anwendung. Das true senkt die Priorität des Renderers auf RENDERER_PRIORITY_WAIVED wenn das zugehörige WebView-Objekt nicht mehr sichtbar ist. In anderen bedeutet das Argument true, dass es für deine App egal ist, hält das System den Renderer-Prozess aktiv. Diese niedrigere Prioritätsebene wird es wahrscheinlich, dass der Renderer-Prozess aufgrund von unzureichendem Arbeitsspeicher beendet wird. Situationen.

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

Weitere Informationen dazu, wie das System mit unzureichendem Arbeitsspeicher umgeht, finden Sie unter Prozesse und App Lebenszyklus.