Android menyediakan beberapa API untuk membantu Anda mengelola
WebView
objek yang menampilkan konten web dalam aplikasi Anda.
Halaman ini menjelaskan cara menggunakan API ini untuk berfungsi dengan WebView
secara lebih efektif, untuk meningkatkan stabilitas dan keamanan aplikasi Anda.
Version API
Mulai Android 7.0 (level API 24), pengguna dapat memilih di antara beberapa
paket yang berbeda untuk menampilkan konten web dalam objek WebView
.
Class AndroidX.webkit
library ini menyertakan
getCurrentWebViewPackage()
metode untuk mengambil informasi yang terkait dengan paket yang menampilkan web
konten dalam aplikasi Anda. Metode ini berguna ketika menganalisis {i>error<i} yang hanya terjadi
saat aplikasi Anda mencoba menampilkan konten web menggunakan paket
implementasi WebView
.
Untuk menggunakan metode ini, tambahkan logika yang ditampilkan dalam cuplikan kode berikut:
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);
Layanan Google Safe Browsing
Untuk memberi pengguna pengalaman penjelajahan yang lebih aman, WebView
objek memverifikasi URL menggunakan
Google Safe Browsing,
yang memungkinkan aplikasi Anda menampilkan peringatan kepada pengguna saat mereka mencoba menavigasi ke
situs web yang berpotensi tidak aman.
Meskipun nilai default EnableSafeBrowsing
adalah true,
adalah ketika Anda mungkin hanya ingin mengaktifkan
Safe Browsing secara kondisional atau
menonaktifkannya. Android 8.0 (level API 26) dan yang lebih baru mendukung penggunaan
setSafeBrowsingEnabled()
untuk mengaktifkan/menonaktifkan Safe Browsing untuk setiap objek WebView
.
Jika Anda ingin semua objek WebView
memilih untuk tidak mengaktifkan Safe Browsing
pemeriksaan, tambahkan elemen <meta-data>
berikut ke metode
file manifes:
<manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" /> ... </application> </manifest>
Menentukan tindakan terprogram
Saat instance WebView
mencoba memuat halaman yang
diklasifikasikan oleh Google sebagai ancaman yang diketahui, WebView
secara default
menampilkan interstisial yang memperingatkan pengguna tentang ancaman yang diketahui. Layar ini memberikan
memberi pengguna opsi untuk tetap memuat URL atau kembali ke halaman sebelumnya yang
aman.
Jika menargetkan Android 8.1 (API level 27) atau yang lebih baru, Anda dapat menentukan secara terprogram bagaimana aplikasi Anda merespons ancaman yang diketahui dalam cara:
- Anda dapat mengontrol apakah aplikasi Anda melaporkan ancaman yang diketahui ke tab Menjelajah.
- Anda bisa membuat aplikasi secara otomatis melakukan tindakan tertentu—seperti kembali agar aman—setiap kali menemukan URL yang diklasifikasikan sebagai ancaman yang diketahui.
Cuplikan kode berikut mengilustrasikan cara menginstruksikan instance aplikasi Anda
WebView
untuk selalu kembali agar aman setelah bertemu dengan ancaman yang diketahui
ancaman:
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(); } } }
HTML5 Geolocation API
Untuk aplikasi yang menargetkan Android 6.0 (API level 23) dan yang lebih baru, Geolocation API
hanya didukung di origin yang aman, seperti HTTPS. Setiap permintaan ke
Geolocation API pada asal yang tidak aman akan otomatis ditolak tanpa memanggil
metode onGeolocationPermissionsShowPrompt()
yang sesuai.
Memilih tidak ikut pengumpulan metrik
WebView
dapat mengupload data diagnostik anonim untuk
Google saat pengguna memberikan izin. Data dikumpulkan per aplikasi
untuk setiap aplikasi yang membuat instance WebView
. Anda dapat memilih untuk tidak ikut serta
dengan membuat tag berikut dalam atribut
Elemen <application>
:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" /> </application> </manifest>
Data hanya diupload dari aplikasi jika pengguna mengizinkan dan aplikasi tidak keluar. Untuk informasi selengkapnya tentang memilih tidak ikut menggunakan data diagnostik pelaporan, lihat Privasi pengguna di WebView pelaporan.
Termination Handling API
Penghentian Penanganan API menangani kasus saat proses perender untuk
WebView
hilang, karena sistem mematikan perender untuk mengklaim kembali
memori yang diperlukan atau karena
proses perender tidak berfungsi. Dengan menggunakan API ini, Anda
membiarkan aplikasi Anda terus berjalan, meskipun proses perender pergi.
Jika perender tidak bekerja saat memuat laman web tertentu, mencoba untuk
memuat halaman yang sama lagi dapat menyebabkan objek WebView
baru
menunjukkan perilaku error rendering yang sama.
Cuplikan kode berikut mengilustrasikan cara menggunakan API ini dalam
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 Importance API
Jika WebView
objek
beroperasi di
mode multiproses, Anda memiliki fleksibilitas terkait cara aplikasi menangani
situasi kehabisan memori. Anda dapat menggunakan Renderer Importance API, yang diperkenalkan di
Android 8.0, untuk menyetel kebijakan prioritas bagi perender yang ditetapkan ke
Objek WebView
. Secara khusus, Anda mungkin
ingin bagian utama dari
aplikasi Anda untuk terus berjalan ketika perender yang menampilkan aplikasi Anda
Objek WebView
dihentikan. Anda mungkin melakukannya. Misalnya, jika Anda
jangan tampilkan objek WebView
dalam waktu yang lama sehingga
sistem bisa memperoleh kembali memori
yang digunakan perender.
Cuplikan kode berikut menunjukkan cara menetapkan prioritas ke perender
proses yang terkait dengan objek WebView
aplikasi Anda:
Kotlin
val myWebView: WebView = ... myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)
Java
WebView myWebView; myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);
Dalam cuplikan khusus ini, prioritas perender sama dengan—atau
terikat pada—prioritas default untuk aplikasi. true
menurunkan prioritas perender menjadi
RENDERER_PRIORITY_WAIVED
saat objek WebView
terkait tidak lagi terlihat. Di
kata, argumen true
menunjukkan bahwa aplikasi Anda tidak peduli apakah
sistem menjaga
proses perender tetap hidup. Faktanya, tingkat prioritas
yang lebih rendah ini
memungkinkan proses perender dihentikan saat kehabisan memori
situasi.
Untuk mempelajari lebih lanjut cara sistem menangani situasi memori rendah, lihat Proses dan aplikasi siklus proses.