يصف هذا الدليل مزايا مكتبة Jetpack Webkit، ويوضّح طريقة عملها وكيفية تنفيذها في مشاريعك.
نظرة عامة
تُعدّ عروض الويب جزءًا أساسيًا من تطوير تطبيقات Android، ولكن قد يكون من الصعب في بعض الأحيان إدارتها بسبب الاختلافات في الميزات بين إصدارات نظام التشغيل Android المختلفة. يوفّر كل إصدار من نظام التشغيل Android مجموعة ثابتة من واجهات برمجة التطبيقات لعرض الويب. بما أنّ إصدار Android يتم بوتيرة أبطأ من إصدار WebView، قد لا تغطّي واجهات برمجة التطبيقات في Android كل ميزات WebView المتاحة. ويؤدي ذلك إلى طرح الميزات بوتيرة أبطأ وزيادة تكاليف الاختبار.
تحلّ مكتبة Jetpack Webkit هذه المشاكل من خلال العمل كطبقة توافق والاستفادة من أحدث حزمة APK لتطبيق WebView على جهاز المستخدم. تحتوي هذه المكتبة أيضًا على واجهات برمجة تطبيقات جديدة وحديثة لا تتوفّر إلا فيها.
ما هي مزايا استخدام Jetpack Webkit؟
بالإضافة إلى توفير التوافق بين الإصدارات المختلفة، توفّر Jetpack Webkit أيضًا واجهات برمجة تطبيقات جديدة وحديثة يمكنها تبسيط عملية التطوير وتحسين وظائف تطبيقك:
تفعيل المصادقة الحديثة: يمكن أن تتعامل WebView بسلاسة مع معايير مصادقة الويب الحديثة، مثل WebAuthn، ما يتيح تسجيلات الدخول المستندة إلى مفاتيح المرور. تمنحك مكتبة
androidx.webkitإمكانية التحكّم الكامل في عملية الدمج هذه باستخدام طريقةWebSettingsCompat.setWebAuthenticationSupport، التي يمكنك استخدامها لضبط مستوى الدعم الذي يتطلبه تطبيقك.تحسين الأداء: يمكنك تحسين أداء WebView باستخدام واجهات برمجة التطبيقات، مثل
setBackForwardCacheEnabled، أو تقليل وقت استجابة التنقّل باستخدام واجهات برمجة التطبيقات للتحميل مبني على توقّع، مثلprefetchUrlAsyncوprerenderUrlAsync. لمزيد من المعلومات، يُرجى الاطّلاع على التحميل المبني على توقّع في WebView.زيادة الثبات: يمكنك استرداد عمليات العرض المتوقفة أو غير المستجيبة بدون حدوث أعطال. لمزيد من المعلومات، يُرجى الاطّلاع على
WebViewRenderProcess#terminate.التحكّم الدقيق في بيانات التصفّح: لحذف بيانات التصفّح التي خزّنتها WebView لمصادر معيّنة، استخدِم فئة
WebStorageCompat.توفير إمكانية التنقل في الصفحة المحسّنة: استخدِم
WebViewCompat.navigateبدلاً منWebView.loadUrlللتحكّم الدقيق في التنقّل، واستبدال إدخالات السجلّ ، ودعم عنوان الحالة المحفوظة، وتتبُّع مراحل النشاط المرتبطة باستخدامNavigationListener. لمزيد من المعلومات، يُرجى الاطّلاع على التنقّل المحسّن بين الصفحات باستخدام WebViewCompat.navigate.تحسين إدارة الحالة: يمكنك الحماية من
TransactionTooLargeExceptionمن خلال ضبط الحد الأقصى لعدد البايت أثناء تسلسل الحالة. لمزيد من المعلومات، يُرجى الاطّلاع على إدارة حالة WebView بكفاءة.
التعرّف على المكوّنات
لاستخدام Jetpack Webkit بفعالية، يجب فهم العلاقة بين المكوّنات التالية:
Android System WebView: هو محرّك العرض المستند إلى Chromium الذي تُحدّثه Google بانتظام من خلال "متجر Google Play" بالوتيرة نفسها التي يتم بها تحديث Chrome. يحتوي على أحدث الميزات ويوفر رمز التنفيذ الأساسي لجميع واجهات برمجة التطبيقات لعرض الويب.
Framework APIs (
android.webkit): هي واجهات برمجة التطبيقات الثابتة لإصدار معيّن من نظام التشغيل Android. على سبيل المثال، لا يمكن لتطبيق على Android 10 الوصول إلا إلى واجهات برمجة التطبيقات التي كانت متاحة عند إصدار هذا الإصدار. لذا، لا يمكنه استخدام الميزات الجديدة التي تمت إضافتها إلى حزمة APK لتطبيق WebView في التحديثات الأحدث. على سبيل المثال، للحصول على مؤشر لعملية عرض غير مستجيبة باستخدامWebView#getWebViewRenderProcess()، لا يمكنك استدعاء هذه الطريقة إلا على Android 10 والإصدارات الأحدث.Jetpack Webkit Library (
androidx.webkit): هي مكتبة صغيرة مجمّعة في تطبيقك. تعمل هذه المكتبة كجسر يستدعي حزمة APK لتطبيق WebView، بدلاً من استدعاء واجهات برمجة التطبيقات المحدّدة في منصة Android التي لها إصدار ثابت من نظام التشغيل. بهذه الطريقة، حتى عند تثبيت تطبيق على جهاز يعمل بإصدار قديم من نظام التشغيل، مثل Android 10، يمكن للتطبيق استخدام أحدث ميزات WebView. على سبيل المثال،WebViewCompat.getWebViewRenderProcess()تعمل بطريقة مشابهة لواجهة برمجة التطبيقات في إطار العمل، ولكن يمكن أيضًا استدعاء هذه الطريقة على جميع إصدارات نظام التشغيل قبل Android 10.
إذا كانت واجهة برمجة التطبيقات متاحة في كلٍّ من إطار العمل وJetpack Webkit، ننصحك باختيار إصدار Jetpack Webkit. يساعد ذلك في ضمان سلوك متّسق والتوافق مع أوسع مجموعة من الأجهزة.
تفاعل Jetpack Webkit مع حزمة APK
يتم تنفيذ واجهات برمجة التطبيقات في Jetpack Webkit على جزأين:
Static Jetpack Webkit: تحتوي مكتبة Jetpack Webkit الثابتة على جزء صغير من الرمز المسؤول عن تنفيذ واجهة برمجة التطبيقات.
WebView APK: تحتوي حزمة APK لتطبيق WebView على معظم الرمز.
يستدعي تطبيقك واجهة برمجة التطبيقات Jetpack Webkit، التي تستدعي بعد ذلك حزمة APK لتطبيق WebView.
يمكنك التحكّم في إصدار Jetpack Webkit في تطبيقك، ولكن لا يمكنك التحكّم في تحديثات حزمة APK لتطبيق WebView على أجهزة المستخدمين. بشكلٍ عام، يستخدم معظم المستخدمين أحدث إصدارات حزمة APK لتطبيق WebView، ولكن يجب أن يحرص تطبيقك على عدم استدعاء واجهات برمجة التطبيقات التي لا يتيحها هذا الإصدار من حزمة APK لتطبيق WebView.
تزيل Jetpack Webkit أيضًا الحاجة إلى التحقّق من إصدارات WebView يدويًا.
لتحديد ما إذا كانت ميزة معيّنة متاحة، تحقَّق من الثابت الخاص بالميزة. على
سبيل المثال، WebViewFeature.WEB_AUTHENTICATION.
كيفية عملهما معًا
تُسدّ Jetpack Webkit الفجوة بين واجهة برمجة التطبيقات الثابتة في إطار العمل وحزمة APK لتطبيق WebView التي يتم تحديثها بشكل متكرّر. عند استخدام واجهة برمجة التطبيقات Jetpack Webkit مع نمط رصد الميزات، تُجري المكتبة عملية تحقّق لمعرفة ما إذا كانت حزمة APK لتطبيق WebView المثبّتة على جهاز المستخدم تتيح الميزة. ويوفّر ذلك ميزة عدم الحاجة إلى التحقّق من إصدار نظام التشغيل Android (إطار العمل).
إذا كانت حزمة APK لتطبيق WebView إصدارًا حديثًا بما يكفي، تستدعي المكتبة الميزة. وإذا لم يكن كذلك، تُبلغ المكتبة بأنّ الميزة غير متاحة، ما يمنع تطبيقك من حدوث أعطال ويسمح لك بالتعامل مع الموقف بسلاسة.
مقارنة بين Jetpack Webkit وواجهات برمجة التطبيقات في إطار العمل
يقارن هذا القسم بين طرق التنفيذ مع مكتبة Jetpack Webkit وبدونها:
تفعيل المصادقة الحديثة (WebAuthn)
بدون Jetpack Webkit
لا يمكن إجراء ذلك من خلال واجهات برمجة التطبيقات في إطار العمل.
باستخدام Jetpack Webkit
تستفيد من WebViewFeature.WEB_AUTHENTICATION لإجراء عمليات التحقّق من التوافق.
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_AUTHENTICATION)) {
WebSettingsCompat.setWebAuthenticationSupport(
webView.settings,
WebSettingsCompat.WEB_AUTHENTICATION_SUPPORT_FOR_APP
)
}
حذف البيانات لمصدر معيّن (مساحة تخزين خاصة بالموقع الإلكتروني)
بدون Jetpack WebKit
لا تتوفّر واجهة برمجة تطبيقات مباشرة لمحو بيانات مصدر معيّن. غالبًا ما يتطلب ذلك محو جميع البيانات.
باستخدام Jetpack WebKit
تستخدِم واجهات برمجة التطبيقات المتوافقة لحذف البيانات بدقة. يمكنك استخدام أيٍّ من الخيارَين التاليَين:
WebStorageCompat.getInstance().deleteBrowsingData()
أو
WebStorageCompat.getInstance().deleteBrowsingDataForSite()
الحصول على إصدار WebView
بدون Jetpack WebKit
تستخدِم فئة إطار العمل العادية.
val webViewPackage = WebView.getCurrentWebViewPackage()
باستخدام Jetpack WebKit
تستخدِم طبقة التوافق لاسترداد البيانات بأمان أكبر.
val webViewPackage = WebViewCompat.getCurrentWebViewPackage()
التعامل مع عملية عرض غير مستجيبة (عميل عملية العرض)
بدون Jetpack WebKit
تستخدِم طريقة إطار العمل العادية.
webView.setWebViewRenderProcessClient(myClient)
باستخدام Jetpack WebKit
تستخدِم WebViewCompat وعملية تحقّق من الميزة لضبط العميل.
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE)) {
WebViewCompat.setWebViewRenderProcessClient(webView, myClient)
}
للحصول على إرشادات حول تنفيذ استراتيجيات استرداد البيانات بعد حدوث أعطال، يُرجى الاطّلاع على التعامل مع إنهاء WebView. لمعرفة تفاصيل واجهة برمجة التطبيقات، يُرجى الاطّلاع على androidx.webkit
مستندات مرجع.
إدارة الحالة المحفوظة وحجم المعاملة
تتيح لك واجهة برمجة التطبيقات WebViewCompat.saveState فرض حدود على عدد البايت وإزالة السجلّ التالي أثناء التسلسل، ما يمنع حدوث أعطال TransactionTooLargeException مع الاحتفاظ بسجلّ التنقّل الأساسي.
بدون Jetpack WebKit
تستخدِم طريقة إطار العمل العادية، التي تسلسل مكدس التنقّل بالكامل بدون حدود على الحجم ويمكن أن تؤدي إلى حدوث TransactionTooLargeException إذا تجاوزت الحمولة حدّ المعاملة البالغ ميغابايت واحد في Android.
webView.saveState(outState)
باستخدام Jetpack WebKit
تستخدِم WebViewCompat لفرض حد أقصى لعدد البايت أو إزالة إدخالات التنقّل التالي، ما يحمي من حالات تجاوز المعاملات.
WebViewCompat.saveState(webView, outState, maxSizeBytes)
لمزيد من المعلومات، يُرجى الاطّلاع على إدارة حالة WebView بكفاءة.
التنقّل بين الصفحات وتتبُّع مراحل النشاط
للتنقّل بين صفحات الويب مع إمكانية استبدال إدخالات السجلّ ودعم عنوان الحالة المحفوظة وعمليات معاودة الاتصال المرتبطة بمراحل النشاط، استخدِم WebViewCompat.navigate بدلاً من WebView.loadUrl.
بدون Jetpack WebKit
تستخدِم WebView.loadUrl، التي لا تتيح استبدال إدخالات السجلّ أو تتبُّع عمليات الاستدعاء في إحدى مراحل النشاط المرتبطة.
webView.loadUrl("https://www.example.com")
باستخدام Jetpack WebKit
تستخدِم WebViewCompat.navigate مع NavigationParameters لاستبدال إدخالات السجلّ والاحتفاظ بالعناوين المخصّصة في الحالة المحفوظة وتتبُّع حالات التنقّل.
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEBVIEW_NAVIGATE_EXPERIMENTAL_V1)) {
val params = NavigationParameters.Builder()
.setShouldReplaceCurrentEntry(true)
.build()
val navigation = WebViewCompat.navigate(webView, "https://www.example.com", params)
} else {
webView.loadUrl("https://www.example.com")
}
لمزيد من المعلومات حول تتبُّع التنقّل وإعداد المَعلمات، يُرجى الاطّلاع على التنقّل المحسّن بين الصفحات باستخدام WebViewCompat.navigate.
دمج Jetpack Webkit في الرمز
يؤدي استخدام Jetpack Webkit إلى زيادة إمكانات فئة WebView العادية، ولكنّه لا يحلّ محلّ فئة WebView الأصلية بالكامل.
يمكنك مواصلة استخدام فئة android.webkit.WebView. يمكنك إضافتها إلى تنسيقات XML والحصول على مرجع للمثيل في الرمز. للوصول إلى ميزات إطار العمل العادية، يمكنك مواصلة استدعاء الطرق مباشرةً على مثيل WebView أو عنصر الإعدادات الخاص به.
للوصول إلى الميزات الحديثة، استخدِم طرق المساعد الثابتة التي توفّرها Jetpack Webkit، مثل WebViewCompat وWebSettingsCompat. عليك تمرير مثيل WebView الحالي إلى هذه الطرق.
Kotlin
import android.webkit.WebView
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
// You still get your WebView instance the standard way.
val webView: WebView = findViewById(R.id.my_webview)
// To enable a modern feature, you pass that instance to a Jetpack Webkit helper.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)
}
Java
import android.webkit.WebView;
import androidx.webkit.WebSettingsCompat;
import androidx.webkit.WebViewFeature;
// You still get your WebView instance the standard way.
WebView webView = findViewById(R.id.my_webview);
// To enable a modern feature, you pass that instance to a Jetpack Webkit helper.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON);
}
تنفيذ Jetpack Webkit
لتنفيذ Jetpack Webkit، استخدِم الإجراء التالي.
الخطوة 1: إضافة الاعتمادية
في ملف build.gradle.kts أو build.gradle الخاص بالوحدة، أدرِج التبعية التالية لإضافة Jetpack Webkit:
Groovy
dependencies { implementation "androidx.webkit:webkit:1.16.0" }
Kotlin
dependencies { implementation("androidx.webkit:webkit:1.16.0") }
تحتوي Jetpack Webkit على أغلفة بسيطة، لذا يكون التأثير في حجم تطبيقك ضئيلاً.
الخطوة 2: استخدام نمط رصد الميزات
لمنع حدوث أعطال عند استدعاء واجهات برمجة التطبيقات غير المتاحة، استخدِم عمليات التحقّق من الميزات. ننصحك بإحاطة كل استدعاء لواجهة برمجة التطبيقات بعملية تحقّق من الميزة، وربما التفكير في منطق احتياطي في حال عدم توفّر واجهة برمجة التطبيقات.
ننصحك باستخدام النمط التالي لاستخدام واجهة برمجة تطبيقات حديثة لعرض الويب:
Kotlin
import android.webkit.WebView
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature
val webView: WebView = findViewById(R.id.my_webview)
// Before you use a modern API, first check if it is supported.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
// If the check passes, it is safe to call the API.
WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)
} else {
// Optionally, provide a fallback for older WebView versions.
}
Java
import android.webkit.WebView;
import androidx.webkit.WebSettingsCompat;
import androidx.webkit.WebViewFeature;
WebView webView = findViewById(R.id.my_webview);
// Before you use a modern API, first check if it is supported.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
// If the check passes, it is safe to call the API.
WebSettingsCompat.setForceDark(webView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
} else {
// Optionally, provide a fallback for older WebView versions.
}
يساعد هذا النمط في ضمان قوة التطبيق. بما أنّ عملية التحقّق من الميزة يتم تشغيلها أولاً، لا يتعطّل التطبيق إذا لم تكن الميزة متاحة. إنّ الأداء الإضافي لعملية التحقّق WebViewFeature#isFeatureSupported ضئيل.