تبسيط عملية تنفيذ WebView باستخدام Jetpack Webkit

يوضّح هذا الدليل مزايا مكتبة Jetpack Webkit، ويشرح طريقة عملها وكيفية تنفيذها في مشاريعك.

نظرة عامة

تُعدّ WebViews جزءًا أساسيًا من عملية تطوير تطبيقات Android، ولكن قد يصعب في بعض الأحيان إدارة هذه المكوّنات بسبب التناقضات في الميزات بين إصدارات نظام التشغيل Android المختلفة. يوفّر كل إصدار من نظام التشغيل Android مجموعة ثابتة من واجهات برمجة التطبيقات WebView. بما أنّ إصدارات Android تتم بوتيرة أبطأ من إصدارات WebView، قد لا تغطّي واجهات برمجة التطبيقات في Android كل ميزات WebView المتاحة. ويؤدي ذلك إلى طرح الميزات بشكل أبطأ وزيادة تكاليف الاختبار.

تحلّ حزمة Jetpack Webkit هذه المشاكل من خلال العمل كطبقة توافق والاستفادة من حزمة APK الحديثة لمكوّن WebView على جهاز المستخدم. وتحتوي أيضًا على واجهات برمجة تطبيقات جديدة وحديثة متاحة حصريًا في هذه المكتبة.

لماذا يُنصح باستخدام Jetpack Webkit؟

بالإضافة إلى توفير التوافق مع الإصدارات المختلفة، يوفّر Jetpack Webkit أيضًا واجهات برمجة تطبيقات جديدة وحديثة يمكنها تبسيط عملية التطوير وتحسين وظائف تطبيقك، وهي:

  • تفعيل المصادقة الحديثة: يمكن لمكوّن WebView التعامل بسلاسة مع معايير المصادقة الحديثة على الويب، مثل WebAuthn، ما يتيح عمليات تسجيل الدخول المستندة إلى مفاتيح المرور. تمنحك مكتبة androidx.webkit إمكانية التحكّم الكامل في عملية الدمج هذه باستخدام طريقة WebSettingsCompat.setWebAuthenticationSupport()، التي يمكنك استخدامها لتحديد مستوى الدعم الذي يتطلّبه تطبيقك.

  • تحسين الأداء: يمكنك تحسين أداء WebView بما يتناسب مع حالات استخدام تطبيقك من خلال واجهات برمجة التطبيقات، مثل prefetchUrlAsync وprerenderUrlAsync وsetBackForwardCacheEnabled.

  • زيادة الثبات: استرداد عمليات العرض المتوقفة أو غير المستجيبة بدون حدوث أعطال لمزيد من المعلومات، يُرجى الاطّلاع على WebViewRenderProcess#terminate().

  • توفير تحكّم دقيق في بيانات التصفّح: لحذف بيانات التصفّح التي يخزّنها WebView لمصادر محدّدة، استخدِم الفئة WebStorageCompat.

فهم المكوّنات

لاستخدام Jetpack Webkit بفعالية، يجب فهم العلاقة بين المكوّنات التالية:

  • عرض ويب نظام Android: هذا هو محرّك العرض المستند إلى Chromium الذي تحدّثه Google بانتظام من خلال "متجر Google Play" بالوتيرة نفسها التي يتم بها تحديث Chrome. ويحتوي على أحدث الميزات ويوفر رمز التنفيذ الأساسي لجميع واجهات برمجة التطبيقات WebView.

  • واجهات برمجة التطبيقات الخاصة بإطار العمل (android.webkit): هي واجهات برمجة التطبيقات التي تم تحديدها لإصدار معيّن من نظام التشغيل Android. على سبيل المثال، لا يمكن لتطبيق على نظام التشغيل Android 10 الوصول إلا إلى واجهات برمجة التطبيقات التي كانت متاحة عند إصدار هذا الإصدار. لذا، لا يمكنه استخدام الميزات الجديدة التي تمت إضافتها إلى حزمة APK الخاصة بـ WebView في التحديثات الأحدث. على سبيل المثال، للتعامل مع أداة عرض لا تستجيب باستخدام WebView#getWebViewRenderProcess()، يمكنك استدعاء هذه الأداة على الإصدار 10 من نظام التشغيل Android والإصدارات الأحدث فقط.

  • مكتبة Jetpack Webkit (androidx.webkit): هي مكتبة صغيرة مضمّنة في تطبيقك. تعمل هذه المكتبة كجسر يستدعي حزمة APK الخاصة بـ WebView، بدلاً من استدعاء واجهات برمجة التطبيقات المحدّدة في منصة Android التي تتضمّن إصدارًا ثابتًا من نظام التشغيل. بهذه الطريقة، حتى عند تثبيت تطبيق على جهاز يعمل بإصدار قديم من نظام التشغيل، مثل Android 10، يمكن للتطبيق استخدام أحدث ميزات WebView. على سبيل المثال، تعمل الدالة WebViewCompat.getWebViewRenderProcess() بشكل مشابه لواجهة برمجة التطبيقات Framework API، ولكن يمكن أيضًا استدعاؤها على جميع إصدارات نظام التشغيل قبل Android 10.

إذا كانت واجهة برمجة التطبيقات متاحة في كلّ من إطار العمل وJetpack Webkit، ننصحك باختيار إصدار Jetpack Webkit. ويساعد ذلك في ضمان سلوك متسق وتوافق مع أكبر مجموعة من الأجهزة.

التفاعل بين Jetpack Webkit وحِزم APK

يتم تنفيذ واجهات برمجة التطبيقات في Jetpack Webkit على جزأين:

  • Static Jetpack Webkit: تحتوي مكتبة Static Jetpack Webkit على جزء صغير من الرمز البرمجي المسؤول عن تنفيذ واجهة برمجة التطبيقات.

  • حزمة APK الخاصة بمكوّن WebView: تحتوي حزمة APK الخاصة بمكوّن WebView على معظم الرموز البرمجية.

يطلب تطبيقك Jetpack Webkit API، الذي يطلب بدوره حزمة APK الخاصة بمكوّن WebView.

مع أنّك تتحكّم في إصدار Jetpack Webkit في تطبيقك، لا يمكنك التحكّم في تحديثات حزمة APK الخاصة بـ WebView على أجهزة المستخدمين. بشكل عام، يستخدم معظم المستخدمين أحدث إصدارات حزمة APK الخاصة بـ WebView، ولكن يجب أن يتوخّى تطبيقك الحذر كي لا يستدعي واجهات برمجة تطبيقات لا يتوافق معها إصدار حزمة APK الخاص بـ WebView.

تتجاهل Jetpack Webkit أيضًا الحاجة إلى التحقّق من إصدارات WebView يدويًا. لتحديد ما إذا كانت إحدى الميزات متاحة، ابحث عن ثابت الميزة. على سبيل المثال، WebViewFeature.WEB_AUTHENTICATION.

كيف تعمل معًا؟

تعمل Jetpack Webkit على سد الفجوة بين واجهة برمجة التطبيقات الثابتة Framework API وحزمة APK الخاصة بـ WebView التي يتم تعديلها بشكل متكرر. عند استخدام Jetpack Webkit API مع نمط رصد الميزات، تجري المكتبة عملية تحقّق لمعرفة ما إذا كانت الميزة متوافقة مع حزمة APK الخاصة بـ WebView المثبَّتة على جهاز المستخدم. ويوفّر ذلك ميزة عدم الحاجة إلى التحقّق من إصدار نظام التشغيل Android (الإطار).

إذا كان إصدار حزمة APK من WebView حديثًا بما يكفي، ستفعّل المكتبة الميزة. وإذا لم يكن الأمر كذلك، سيُبلغك بأنّ الميزة غير متاحة، ما يمنع تطبيقك من تعطّله ويسمح لك بالتعامل مع الموقف بشكل سليم.

مقارنة واجهات برمجة التطبيقات Jetpack Webkit وFramework

يقارن هذا القسم بين طرق التنفيذ مع مكتبة 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)
}

لمزيد من المعلومات، اطّلِع على المستندات المرجعية الخاصة بـ androidx.webkit.

دمج 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.14.0"
}

Kotlin

dependencies {
    implementation("androidx.webkit:webkit:1.14.0")
}

يحتوي Jetpack Webkit على برامج تضمين بسيطة، لذا يكون التأثير على حجم تطبيقك ضئيلاً.

الخطوة 2: استخدام نمط رصد الميزات

لمنع حدوث أعطال عند استدعاء واجهات برمجة تطبيقات غير متاحة، استخدِم عمليات التحقّق من الميزات. ننصحك بإجراء فحص للميزات قبل كل استدعاء لواجهة برمجة التطبيقات، وربما التفكير في منطق احتياطي في حال عدم توفّر واجهة برمجة التطبيقات.

ننصحك باتّباع النمط التالي لاستخدام واجهة برمجة تطبيقات حديثة لـ WebView:

import android.webkit.WebView
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewFeature

// In your Kotlin code where you configure your WebView
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.
}

يساعد هذا النمط في ضمان قوة التطبيق. وبما أنّ عملية التحقّق من توفّر الميزة تتم أولاً، لن يتعطّل التطبيق إذا لم تكن الميزة متاحة. إنّ تكلفة الأداء الإضافية لعملية التحقّق من WebViewFeature#isFeatureSupported() ضئيلة.