Android, कई एपीआई उपलब्ध कराता है. इनकी मदद से, WebView
उन ऑब्जेक्ट को मैनेज किया जा सकता है जो आपके ऐप्लिकेशन में वेब कॉन्टेंट दिखाते हैं.
इस पेज पर बताया गया है कि इन एपीआई का इस्तेमाल करके, WebView ऑब्जेक्ट के साथ ज़्यादा असरदार तरीके से काम कैसे किया जा सकता है. इससे आपके ऐप्लिकेशन के बिना क्रैश या फ़्रीज़ हुए काम करने की क्षमता और सुरक्षा को बेहतर बनाया जा सकता है.
Version API
Android 7.0 (एपीआई लेवल 24) से, उपयोगकर्ताओं के पास WebView ऑब्जेक्ट में वेब कॉन्टेंट दिखाने के लिए, कई अलग-अलग पैकेज में से किसी एक को चुनने का विकल्प होता है. Jetpack Webkit लाइब्रेरी में, getCurrentWebViewPackage() तरीका शामिल होता है. इसका इस्तेमाल, उस पैकेज से जुड़ी जानकारी पाने के लिए किया जाता है जो आपके ऐप्लिकेशन में वेब कॉन्टेंट दिखाता है. यह तरीका तब काम आता है, जब उन गड़बड़ियों का विश्लेषण करना हो जो सिर्फ़ तब होती हैं, जब आपका ऐप्लिकेशन WebView के किसी खास पैकेज के इंप्लीमेंटेशन का इस्तेमाल करके वेब कॉन्टेंट दिखाता है.
इस तरीके का इस्तेमाल करने के लिए, यहां दिए गए कोड स्निपेट में दिखाया गया लॉजिक जोड़ें:
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 Safe Browsing Service
अपने उपयोगकर्ताओं को सुरक्षित ब्राउज़िंग का अनुभव देने के लिए, WebView
ऑब्जेक्ट, यूआरएल की पुष्टि करने के लिए
Google सुरक्षित ब्राउज़िंग का इस्तेमाल करते हैं.
इससे आपका ऐप्लिकेशन, उपयोगकर्ताओं को संभावित रूप से असुरक्षित वेबसाइट पर जाने की कोशिश करने पर चेतावनी दिखा पाता है.
EnableSafeBrowsing की डिफ़ॉल्ट वैल्यू भले ही सही हो, लेकिन ऐसे मामले हो सकते हैं जब आपको सुरक्षित ब्राउज़िंग की सुविधा को सिर्फ़ कुछ शर्तों के साथ चालू करना हो या उसे बंद करना हो. Android 8.0 (एपीआई लेवल 26) और इसके बाद के वर्शन में, setSafeBrowsingEnabled() का इस्तेमाल किया जा सकता है. इससे किसी WebView ऑब्जेक्ट के लिए, सुरक्षित ब्राउज़िंग की सुविधा को टॉगल किया जा सकता है.
अगर आपको सभी WebView ऑब्जेक्ट को सुरक्षित ब्राउज़िंग की जांचों से ऑप्ट आउट करना है, तो अपने ऐप्लिकेशन की मेनिफ़ेस्ट फ़ाइल में यह <meta-data> एलिमेंट जोड़ें:
<manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" /> ... </application> </manifest>
प्रोग्राम के हिसाब से होने वाली कार्रवाइयां तय करना
जब WebView किसी ऐसे पेज को लोड करने की कोशिश करता है जिसे Google ने सुरक्षा के लिए खतरा माना है, तो WebView डिफ़ॉल्ट रूप से एक इंटरस्टीशियल दिखाता है. इसमें उपयोगकर्ताओं को सुरक्षा के लिए खतरे की चेतावनी दी जाती है. इस स्क्रीन पर, उपयोगकर्ताओं को यूआरएल लोड करने या किसी ऐसे पिछले पेज पर वापस जाने का विकल्प मिलता है जो सुरक्षित है.
अगर आपका ऐप्लिकेशन Android 8.1 (एपीआई लेवल 27) या उसके बाद के वर्शन को टारगेट करता है, तो प्रोग्राम के हिसाब से यह तय किया जा सकता है कि आपका ऐप्लिकेशन, किसी ज्ञात खतरे का जवाब किस तरह देगा. इसके लिए, इन तरीकों का इस्तेमाल किया जा सकता है:
- आपके पास यह कंट्रोल करने का विकल्प होता है कि आपका ऐप्लिकेशन, सुरक्षित ब्राउज़िंग को ज्ञात खतरों की रिपोर्ट करे या नहीं.
- आपके पास अपने ऐप्लिकेशन को इस तरह से सेट करने का विकल्प होता है कि जब भी उसे किसी ऐसे यूआरएल का पता चले जिसे 'ज्ञात खतरा' के तौर पर क्लासिफ़ाई किया गया है, तो वह अपने-आप कोई खास कार्रवाई करे. जैसे, सुरक्षा मोड पर वापस जाना.
यहां दिए गए कोड स्निपेट में बताया गया है कि WebView के अपने ऐप्लिकेशन इंस्टेंस को यह निर्देश कैसे दें कि किसी ज्ञात खतरे का सामना करने के बाद, वह हमेशा सुरक्षित स्थिति में वापस आ जाए:
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
Android 6.0 (एपीआई लेवल 23) और इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन के लिए, Geolocation API सिर्फ़ सुरक्षित ऑरिजिन पर काम करता है. जैसे, एचटीटीपीएस. सुरक्षित नहीं माने जाने वाले ऑरिजिन से Geolocation API को किए गए किसी भी अनुरोध को, उससे जुड़ी onGeolocationPermissionsShowPrompt() विधि को लागू किए बिना अपने-आप अस्वीकार कर दिया जाता है.
मेट्रिक कलेक्शन से ऑप्ट आउट करना
WebView में, उपयोगकर्ता की सहमति मिलने पर, Google को पहचान छिपाकर गड़बड़ी की जानकारी अपलोड करने की सुविधा होती है. डेटा को हर ऐप्लिकेशन के हिसाब से इकट्ठा किया जाता है. यह डेटा, WebView को इंस्टैंटिएट करने वाले हर ऐप्लिकेशन के लिए इकट्ठा किया जाता है. इस सुविधा से ऑप्ट आउट करने के लिए, मेनिफ़ेस्ट के <application> एलिमेंट में यह टैग बनाएं:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" /> </application> </manifest>
डेटा सिर्फ़ तब किसी ऐप्लिकेशन से अपलोड किया जाता है, जब उपयोगकर्ता सहमति देता है और ऐप्लिकेशन ऑप्ट आउट नहीं करता है. गड़बड़ी की जानकारी देने वाले डेटा की रिपोर्टिंग से ऑप्ट आउट करने के बारे में ज़्यादा जानने के लिए, WebView में उपयोगकर्ता की निजता से जुड़ी रिपोर्टिंग देखें.
Termination Handling API
टर्मिनेशन हैंडलिंग एपीआई उन मामलों को हैंडल करता है जहां किसी WebView ऑब्जेक्ट के लिए रेंडरर प्रोसेस बंद हो जाती है. ऐसा इसलिए होता है, क्योंकि सिस्टम ज़रूरी मेमोरी को वापस पाने के लिए रेंडरर को बंद कर देता है या रेंडरर प्रोसेस क्रैश हो जाती है. इस एपीआई का इस्तेमाल करके, रेंडरर प्रोसेस के बंद होने के बावजूद, अपने ऐप्लिकेशन को चालू रखा जा सकता है.
अगर किसी वेब पेज को लोड करते समय रेंडरर क्रैश हो जाता है, तो उसी पेज को फिर से लोड करने की कोशिश करने पर, नया WebView ऑब्जेक्ट भी रेंडरिंग क्रैश होने की समस्या दिखा सकता है.
नीचे दिए गए कोड स्निपेट में, 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
जब WebView ऑब्जेक्ट मल्टीप्रोसेस मोड में काम करते हैं, तो आपके पास यह तय करने का विकल्प होता है कि मेमोरी भर जाने की स्थिति में आपका ऐप्लिकेशन किस तरह काम करेगा. Android 8.0 में पेश किए गए Renderer Importance API का इस्तेमाल करके, किसी WebView ऑब्जेक्ट को असाइन किए गए रेंडरर के लिए प्राथमिकता की नीति सेट की जा सकती है. खास तौर पर, ऐसा हो सकता है कि आपको अपने ऐप्लिकेशन के मुख्य हिस्से को तब भी चालू रखना हो, जब आपके ऐप्लिकेशन के WebView ऑब्जेक्ट दिखाने वाले रेंडरर को बंद कर दिया गया हो. उदाहरण के लिए, ऐसा तब किया जा सकता है, जब आपको लंबे समय तक WebView ऑब्जेक्ट नहीं दिखाना हो, ताकि सिस्टम उस मेमोरी को वापस पा सके जिसका इस्तेमाल रेंडरर कर रहा था.
यहां दिए गए कोड स्निपेट में, आपके ऐप्लिकेशन के WebView ऑब्जेक्ट से जुड़ी रेंडरर प्रोसेस को प्राथमिकता असाइन करने का तरीका बताया गया है:
Kotlin
val myWebView: WebView = ... myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)
Java
WebView myWebView; myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);
इस स्निपेट में, रेंडरर की प्राथमिकता, ऐप्लिकेशन की डिफ़ॉल्ट प्राथमिकता के बराबर है या उससे जुड़ी है. true आर्ग्युमेंट, रेंडरर की प्राथमिकता को RENDERER_PRIORITY_WAIVED पर सेट कर देता है. ऐसा तब होता है, जब उससे जुड़ा WebView ऑब्जेक्ट अब नहीं दिखता. दूसरे शब्दों में कहें, तो true आर्ग्युमेंट से पता चलता है कि आपके ऐप्लिकेशन को इस बात से कोई फ़र्क़ नहीं पड़ता कि सिस्टम, रेंडरर प्रोसेस को चालू रखता है या नहीं. दरअसल, प्राथमिकता का यह लेवल कम होने की वजह से, मेमोरी खत्म होने की स्थिति में रेंडरर प्रोसेस बंद हो जाती है.
सिस्टम, कम मेमोरी की स्थितियों को कैसे मैनेज करता है, इस बारे में ज़्यादा जानने के लिए, प्रोसेस और ऐप्लिकेशन का लाइफ़साइकल लेख पढ़ें.