Android, uygulamanızda web içeriğini gösteren WebView
nesnelerini yönetmenize yardımcı olmak için çeşitli API'ler sağlar.
Bu sayfada, bu API'leri WebView
nesneleriyle daha verimli bir şekilde çalışmak ve uygulamanızın kararlılığını ve güvenliğini iyileştirmek için nasıl kullanabileceğiniz açıklanmaktadır.
Sürüm API'si
Android 7.0'dan (API düzeyi 24) başlayarak, kullanıcılar bir WebView
nesnesinde web içeriğini görüntülemek için farklı paketler arasından seçim yapabilirler.
AndroidX.webkit kitaplığı, uygulamanızda web içeriğini görüntüleyen paketle ilgili bilgileri getirmek için getCurrentWebViewPackage()
yöntemini içerir. Bu yöntem, yalnızca uygulamanız belirli bir paketin WebView
uygulamasını kullanarak web içeriğini görüntülemeye çalıştığında oluşan hataları analiz ederken yararlıdır.
Bu yöntemi kullanmak için aşağıdaki kod snippet'inde gösterilen mantığı ekleyin:
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);
Google Güvenli Tarama Hizmeti
WebView
, kullanıcılarınıza daha güvenli bir göz atma deneyimi sunmak için URL'leri Google Güvenli Tarama'yı kullanarak doğrular. Bu nesne, uygulamanızın güvenli olmayabilecek bir web sitesine gitmeye çalışan kullanıcılara bir uyarı göstermesini sağlar.
Varsayılan EnableSafeBrowsing
değeri true olsa da, Güvenli Tarama'yı yalnızca koşullu olarak etkinleştirmek veya devre dışı bırakmak isteyebileceğiniz durumlar da vardır. Android 8.0 (API düzeyi 26) ve sonraki sürümler tek bir WebView
nesnesi için Güvenli Tarama'yı açıp kapatmak için setSafeBrowsingEnabled()
kullanımını destekler.
Tüm WebView
nesnelerinin Güvenli Tarama kontrollerini devre dışı bırakmasını istiyorsanız aşağıdaki <meta-data>
öğesini uygulamanızın manifest dosyasına ekleyin:
<manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" /> ... </application> </manifest>
Programatik işlemleri tanımlayın
WebView
örneği, Google tarafından bilinen bir tehdit olarak sınıflandırılan bir sayfayı yüklemeye çalıştığında, WebView
varsayılan olarak bilinen tehdit konusunda kullanıcıları uyaran bir geçiş reklamı gösterir. Bu ekran, kullanıcılara URL'yi yine de yükleme veya önceki güvenli bir sayfaya dönme seçeneği sunar.
Android 8.1 (API düzeyi 27) veya sonraki sürümleri hedeflerseniz uygulamanızın bilinen bir tehdide nasıl tepki vereceğini aşağıdaki yöntemlerle programatik olarak tanımlayabilirsiniz:
- Uygulamanızın, Güvenli Tarama'ya yönelik bilinen tehditleri bildirip bildirmeyeceğini kontrol edebilirsiniz.
- Uygulamanızın, bilinen tehdit olarak sınıflandırılmış bir URL ile her karşılaştığında otomatik olarak belirli bir işlemi (örneğin, güvenliğe geri dönme) gerçekleştirmesini sağlayabilirsiniz.
Aşağıdaki kod snippet'leri, uygulamanızın bilinen bir tehditle karşılaştıktan sonra her zaman güvenli bir duruma geri dönmesi için uygulamanızın WebView
örneklerini nasıl bildireceğinizi gösterir:
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 Coğrafi Konum API'sı
Android 6.0 (API düzeyi 23) ve sonraki sürümleri hedefleyen uygulamalar için Coğrafi Konum API, yalnızca HTTPS gibi güvenli kaynaklarda desteklenir. Güvenli olmayan kaynaklarda Geolocation API'ye yapılan tüm istekler, ilgili onGeolocationPermissionsShowPrompt()
yöntemi çağrılmadan otomatik olarak reddedilir.
Metrik toplamayı devre dışı bırak
WebView
, kullanıcı izin verdiğinde anonim teşhis verilerini Google'a yükleyebilir. Veriler, WebView
somutlaştıran her uygulama için uygulama bazında toplanır. Manifest'in <application>
öğesinde aşağıdaki etiketi oluşturarak bu özelliği devre dışı bırakabilirsiniz:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" /> </application> </manifest>
Veriler yalnızca kullanıcı izin verirse ve uygulama devre dışı bırakmazsa bir uygulamadan yüklenir. Teşhis verileri raporlamasını devre dışı bırakma hakkında daha fazla bilgi için Web Görünümü raporlarında kullanıcı gizliliği bölümüne bakın.
Fesih İşlemi API'si
Fesih İşlemler API'si, sistemin gerekli belleği geri kazanmak için oluşturucuyu sonlandırması veya oluşturucu işleminin çökmesi nedeniyle bir WebView
nesnesine ilişkin oluşturucu sürecinin kaybolduğu durumları ele alır. Bu API'yi kullandığınızda, oluşturucu işlemi kaybolsa bile uygulamanızın çalışmaya devam etmesini sağlarsınız.
Oluşturucu belirli bir web sayfası yüklenirken kilitlenirse aynı sayfanın tekrar yüklenmeye çalışılması yeni bir WebView
nesnesinin aynı oluşturma kilitlenme davranışını göstermesine neden olabilir.
Aşağıdaki kod snippet'inde bu API'nin bir Activity
içinde nasıl kullanılacağı gösterilmektedir:
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; } }
Oluşturucu Önem API'si
WebView
nesneleri çok işlemli modda çalıştığında uygulamanızın bellek yetersizliği durumlarını ele alma konusunda biraz esnekliğe sahip olursunuz. Belirli bir WebView
nesnesine atanan oluşturucu için bir öncelik politikası belirlemek üzere Android 8.0'da sunulan Renderer Importance API'sini kullanabilirsiniz. Özellikle, uygulamanızın WebView
nesnelerini gösteren bir oluşturucu sonlandırıldığında uygulamanızın ana bölümünün çalışmaya devam etmesini isteyebilirsiniz. Örneğin, sistemin oluşturucunun kullandığı belleği geri kazanabilmesi için WebView
nesnesinin uzun süre gösterilmemesini istiyorsanız bunu yapabilirsiniz.
Aşağıdaki kod snippet'inde, uygulamanızın WebView
nesneleriyle ilişkili oluşturucu işlemine nasıl öncelik atanacağı gösterilmektedir:
Kotlin
val myWebView: WebView = ... myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)
Java
WebView myWebView; myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);
Bu belirli snippet'te oluşturucunun önceliği, uygulamanın varsayılan önceliğiyle aynıdır veya bu önceliğe bağlıdır. true
bağımsız değişkeni, ilişkili WebView
nesnesi artık görünür olmadığında oluşturucunun önceliğini RENDERER_PRIORITY_WAIVED
değerine düşürür. Diğer bir deyişle, true
bağımsız değişkeni, uygulamanızın sistemin oluşturucu sürecini canlı tutup tutmadığını umursamadığını gösterir. Aslında bu düşük öncelik düzeyi, oluşturucu işleminin bellek yetersiz durumlarda sonlandırılmasına neden olabilir.
Sistemin düşük bellek durumlarını nasıl ele aldığı hakkında daha fazla bilgi edinmek için Süreçler ve uygulama yaşam döngüsü bölümüne bakın.