Android چندین API ارائه می دهد تا به شما در مدیریت اشیاء WebView
که محتوای وب را در برنامه شما نمایش می دهند کمک کند.
در این صفحه نحوه استفاده از این APIها برای کار با اشیاء WebView
به طور مؤثرتر، بهبود پایداری و امنیت برنامه شما توضیح داده شده است.
نسخه API
با شروع Android 7.0 (سطح API 24)، کاربران می توانند از بین چندین بسته مختلف برای نمایش محتوای وب در یک شی WebView
انتخاب کنند. کتابخانه AndroidX.webkit شامل روش getCurrentWebViewPackage()
برای واکشی اطلاعات مربوط به بسته ای است که محتوای وب را در برنامه شما نمایش می دهد. این روش هنگام تجزیه و تحلیل خطاهایی مفید است که فقط زمانی رخ میدهند که برنامه شما سعی میکند محتوای وب را با استفاده از اجرای یک بسته خاص از WebView
نمایش دهد.
برای استفاده از این روش، منطق نشان داده شده در قطعه کد زیر را اضافه کنید:
کاتلین
val webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext) Log.d("MY_APP_TAG", "WebView version: ${webViewPackageInfo.versionName}")
جاوا
PackageInfo webViewPackageInfo = WebViewCompat.getCurrentWebViewPackage(appContext); Log.d("MY_APP_TAG", "WebView version: " + webViewPackageInfo.versionName);
سرویس مرور ایمن گوگل
برای ارائه تجربه مرور ایمنتر به کاربرانتان، اشیاء WebView
نشانیهای وب را با استفاده از مرور ایمن Google تأیید میکنند، که به برنامه شما اجازه میدهد وقتی کاربران سعی میکنند به یک وبسایت بالقوه ناامن حرکت کنند، هشداری را نشان دهد.
اگرچه مقدار پیشفرض EnableSafeBrowsing
درست است، اما مواردی وجود دارد که ممکن است بخواهید فقط مرور ایمن را به صورت مشروط فعال کنید یا آن را غیرفعال کنید. Android 8.0 (سطح API 26) و نسخه های جدیدتر از استفاده از setSafeBrowsingEnabled()
برای تغییر وضعیت Safe Browsing برای یک شی WebView
منفرد پشتیبانی می کند.
اگر میخواهید تمام اشیاء WebView
از بررسیهای Safe Browsing انصراف دهند، عنصر <meta-data>
زیر را به فایل مانیفست برنامه خود اضافه کنید:
<manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" /> ... </application> </manifest>
اقدامات برنامه ای را تعریف کنید
وقتی نمونهای از WebView
تلاش میکند صفحهای را بارگیری کند که توسط Google به عنوان یک تهدید شناخته شده طبقهبندی شده است، WebView
به طور پیشفرض یک بینابینی را نشان میدهد که به کاربران درباره تهدید شناخته شده هشدار میدهد. این صفحه به کاربران این امکان را می دهد که URL را به هر حال بارگیری کنند یا به صفحه قبلی ایمن بازگردند.
اگر Android 8.1 (سطح API 27) یا جدیدتر را هدف قرار میدهید، میتوانید به روشهای زیر نحوه پاسخ برنامهتان به یک تهدید شناختهشده را به صورت برنامهنویسی تعریف کنید:
- میتوانید کنترل کنید که آیا برنامه شما تهدیدات شناخته شده را به «مرور ایمن» گزارش میدهد یا خیر.
- میتوانید هر بار که با نشانی اینترنتی که بهعنوان یک تهدید شناختهشده طبقهبندی میشود، برنامهتان را مجبور کنید بهطور خودکار یک عمل خاص انجام دهد - مانند بازگشت به ایمنی.
قطعه کد زیر نشان میدهد که چگونه به نمونههای برنامه WebView
دستور دهید که همیشه پس از مواجهه با یک تهدید شناخته شده به حالت امن بازگردند:
کاتلین
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!") } }) } }
جاوا
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!"); } } }); } }
کاتلین
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() } } }
جاوا
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 (سطح API 23) و جدیدتر را هدف قرار میدهند، API مکان جغرافیایی فقط در منابع امن مانند HTTPS پشتیبانی میشود. هرگونه درخواست به API Geolocation در مبداهای غیر ایمن به طور خودکار بدون فراخوانی متد مربوطه onGeolocationPermissionsShowPrompt()
رد می شود.
از مجموعه معیارها انصراف دهید
WebView
این قابلیت را دارد که در صورت رضایت کاربر، داده های تشخیصی ناشناس را در Google آپلود کند. داده ها بر اساس هر برنامه برای هر برنامه ای که یک WebView
را نمونه می کند جمع آوری می شود. میتوانید با ایجاد تگ زیر در عنصر <application>
مانیفست از این ویژگی انصراف دهید:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" /> </application> </manifest>
دادهها فقط در صورتی از برنامه آپلود میشوند که کاربر رضایت دهد و برنامه انصراف ندهد. برای اطلاعات بیشتر در مورد انصراف از گزارش دادههای تشخیصی، به حریم خصوصی کاربر در گزارش WebView مراجعه کنید.
API مدیریت خاتمه
Termination Handling API مواردی را مدیریت میکند که فرآیند رندر برای یک شی WebView
از بین میرود، یا به این دلیل که سیستم رندرکننده را میکشد تا حافظه لازم را بازیابی کند یا به دلیل از کار افتادن فرآیند رندر. با استفاده از این API، به برنامه خود اجازه میدهید به اجرا ادامه دهد، حتی اگر فرآیند رندر از بین برود.
اگر یک رندر هنگام بارگیری یک صفحه وب خاص از کار بیفتد، تلاش برای بارگیری مجدد همان صفحه میتواند باعث شود یک شی WebView
جدید همان رفتار خرابی رندر را نشان دهد.
قطعه کد زیر نحوه استفاده از این API را در یک Activity
نشان می دهد:
کاتلین
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 } }
جاوا
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
در حالت چند پردازشی کار می کنند ، در نحوه مدیریت برنامه شما در موقعیت های خارج از حافظه انعطاف پذیری دارید. میتوانید از Renderer Importance API که در Android 8.0 معرفی شده است، برای تنظیم یک خطمشی اولویت برای رندر اختصاص داده شده به یک شی WebView
خاص استفاده کنید. به طور خاص، ممکن است بخواهید زمانی که یک رندر که اشیاء WebView
برنامه شما را نمایش می دهد، اجرا شود، قسمت اصلی برنامه شما به اجرا ادامه دهد. برای مثال، اگر انتظار دارید که شی WebView
برای مدت طولانی نمایش داده نشود، ممکن است این کار را انجام دهید تا سیستم بتواند حافظه ای را که رندر از آن استفاده می کرد، بازیابی کند.
قطعه کد زیر نحوه اختصاص اولویت به فرآیند رندر مرتبط با اشیاء WebView
برنامه شما را نشان می دهد:
کاتلین
val myWebView: WebView = ... myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true)
جاوا
WebView myWebView; myWebView.setRendererPriorityPolicy(RENDERER_PRIORITY_BOUND, true);
در این قطعه خاص، اولویت رندر مانند اولویت پیشفرض برنامه است یا به آن محدود میشود. زمانی که شی WebView
مرتبط دیگر قابل مشاهده نباشد، آرگومان true
اولویت رندرکننده را به RENDERER_PRIORITY_WAIVED
کاهش میدهد. به عبارت دیگر، یک استدلال true
نشان می دهد که برنامه شما اهمیتی نمی دهد که آیا سیستم فرآیند رندر را زنده نگه می دارد یا خیر. در واقع، این سطح اولویت پایین باعث میشود که فرآیند رندر در موقعیتهای خارج از حافظه از بین برود.
برای کسب اطلاعات بیشتر در مورد نحوه مدیریت سیستم در موقعیتهای کم حافظه، به فرآیندها و چرخه عمر برنامه مراجعه کنید.