ב-Android יש כמה ממשקי API שיכולים לעזור לכם לנהל
WebView
אובייקטים שמציגים תוכן מהאינטרנט באפליקציה.
בדף זה מוסבר איך להשתמש בממשקי ה-API האלה כדי לעבוד עם WebView
אובייקטים יעילים יותר, כדי לשפר את היציבות והאבטחה של האפליקציה.
גרסה API
החל מ-Android 7.0 (רמת API 24), המשתמשים יכולים לבחור מבין כמה
חבילות שונות להצגת תוכן מהאינטרנט באובייקט WebView
.
הפונקציה AndroidX.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
כדי לספק למשתמשים חוויית גלישה בטוחה יותר, WebView
אובייקטים מאמתים כתובות URL באמצעות
גלישה בטוחה של Google,
שמאפשרת לאפליקציה להציג למשתמשים אזהרה כשהם מנסים לעבור אל
אתר שעלול להיות לא בטוח.
למרות שערך ברירת המחדל של EnableSafeBrowsing
הוא True, יש
הם מקרים שבהם תרצו להפעיל רק את הגלישה הבטוחה באופן מותנה, או
להשבית אותה. Android 8.0 (רמת API 26) ואילך תומך ב-
setSafeBrowsingEnabled()
כדי להחליף את המצב של הגלישה הבטוחה לאובייקט WebView
ספציפי.
אם רוצים לבטל את ההסכמה לגלישה הבטוחה בכל WebView
האובייקטים
בדיקות, יש להוסיף את הרכיב <meta-data>
הבא
קובץ מניפסט:
<manifest> <application> <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="false" /> ... </application> </manifest>
להגדיר פעולות פרוגרמטיות
כשמופע של WebView
מנסה לטעון דף
הקטגוריה WebView
מסווגת על ידי Google כאיום ידוע כברירת מחדל
מציגה מודעת מעברון שמזהירה את המשתמשים מפני האיום הידוע. המסך הזה מספק
למשתמשים באפשרות לטעון את כתובת האתר בכל מקרה או לחזור לדף קודם
בטוחים.
אם מטרגטים ל-Android מגרסה 8.1 (רמת API 27) ואילך, אפשר להגדיר האופן שבו האפליקציה מגיבה באופן פרוגרמטי לאיום ידוע במקרים הבאים דרכים:
- באפשרותך לקבוע אם האפליקציה תדווח על איומים מוכרים ל-Safe גלישה.
- אפשר להגדיר שהאפליקציה תבצע באופן אוטומטי פעולה מסוימת, למשל בתור חזרה לדף הבטוח — בכל פעם שהוא נתקל בכתובת אתר בסיווג של איום ידוע.
קטעי הקוד הבאים מראים איך להורות למקרים של האפליקציה
WebView
כדי לחזור למצב הבטוח אחרי שנתקלים
איום:
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(); } } }
ממשק API של HTML5 Geolocation
לאפליקציות שמטרגטות ל-Android 6.0 (רמת API 23) ואילך, Geolocation API
נתמכת רק במקורות מאובטחים, כמו HTTPS. כל בקשה
Geolocation API במקורות לא מאובטחים נדחה באופן אוטומטי בלי להפעיל
רכיב ה-method המתאים של onGeolocationPermissionsShowPrompt()
.
ביטול ההסכמה לאיסוף מדדים
ל-WebView
יש אפשרות להעלות נתוני אבחון אנונימיים אל
Google כשהמשתמש מביע הסכמה. הנתונים נאספים על בסיס כל אפליקציה בנפרד
לכל אפליקציה שמייצרת WebView
. יש לך אפשרות לבטל את ההסכמה
על ידי יצירת התג הבא בקובץ המניפסט
רכיב <application>
:
<manifest> <application> ... <meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" /> </application> </manifest>
העלאת הנתונים מתבצעת מאפליקציה רק אם המשתמש מביע הסכמה וגם האפליקציה לא מבטלת את ההסכמה לכך. מידע נוסף על ביטול ההסכמה להצגת נתוני אבחון לדיווח, ראו פרטיות משתמשים ב-WebView דיווח.
API לטיפול בסיום
ממשק ה-API לסיום טיפול מטפל במקרים שבהם תהליך רינדור עבור
WebView
האובייקט נעלם, כי המערכת הורגת את כלי הרינדור כדי לשחזר אותו
זיכרון נדרש או כי תהליך הרינדור קורס. השימוש ב-API הזה מאפשר לך
לאפשר לאפליקציה להמשיך לפעול, למרות שתהליך הרינדור הופסק.
אם כלי לעיבוד קורס בזמן טעינה של דף אינטרנט מסוים, מתבצע ניסיון
טעינה של אותו הדף שוב עלולה לגרום לאובייקט WebView
חדש
מפגינים אותה התנהגות של קריסת רינדור.
קטע הקוד הבא מדגים איך להשתמש ב-API הזה בתוך
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; } }
ממשק API של רינדור Renderer
כאשר WebView
אובייקטים
לפעול במסגרת
במצב ריבוי עיבודים, יש לכם גמישות מסוימת באופן שבו האפליקציה תטפל
במצבים של חוסר זיכרון. תוכלו להשתמש ב-RendererImportance API, שהושק ב-
Android 8.0, כדי להגדיר מדיניות עדיפות לרינדור שמוקצה
אובייקט 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
מציין שלאפליקציה שלך לא משנה
המערכת משאירה את תהליך הרינדור פעיל. למעשה, רמת העדיפות הנמוכה יותר
סביר להניח שתהליך העיבוד נהרג מחוץ לזיכרון
במצבים מסוימים.
למידע נוסף על האופן שבו המערכת מתמודדת עם מצבים של זיכרון נמוך: תהליכים ואפליקציות במחזור החיים.