ساده‌سازی پیاده‌سازی «وب‌نما» با Jetpack Webkit

این راهنما مزایای کتابخانه Jetpack Webkit را شرح می‌دهد، نحوه عملکرد آن را توضیح می‌دهد، و نحوه پیاده‌سازی آن را در پروژه‌هایتان نشان می‌دهد.

نمای کلی

«وب‌نماها» بخش ضروری توسعه Android هستند، اما گاهی‌اوقات به‌دلیل ناهماهنگی در ویژگی‌ها در نسخه‌های مختلف سیستم‌عامل Android، مدیریت آن‌ها می‌تواند چالش‌برانگیز باشد. هر نسخه سیستم‌عامل Android مجموعه ثابتی از WebView APIs ارائه می‌دهد. چون Android با سرعت کمتری نسبت‌به «وب‌نما» عرضه می‌شود، میاناهای برنامه‌سازی کاربردی Android ممکن است همه ویژگی‌های دردسترس «وب‌نما» را پوشش ندهند. این امر منجر به عرضه کندتر ویژگی و افزایش هزینه‌های آزمایش می‌شود.

Jetpack Webkit با عمل کردن به‌عنوان لایه سازگاری و بهره‌برداری از APK به‌روز «وب‌نما» در دستگاه کاربر، این مشکلات را حل می‌کند. این کتابخانه همچنین حاوی میاناهای برنامه‌سازی کاربردی جدید و مدرنی است که منحصراً در این کتابخانه دردسترس هستند.

چرا باید از Jetpack Webkit استفاده کرد؟

Jetpack Webkit علاوه‌بر ارائه سازگاری بین نسخه‌ها، میاناهای برنامه‌سازی کاربردی جدید و مدرنی نیز ارائه می‌دهد که می‌تواند توسعه را ساده‌تر کند و عملکرد برنامه‌تان را بهبود بخشد:

  • فعال کردن اصالت‌سنجی مدرن: «وب‌نما» می‌تواند به‌طور یکپارچه استانداردهای اصالت‌سنجی وب مدرن مانند WebAuthn را مدیریت کند و ورود به سیستم مبتنی بر گذرکلید را فعال کند. کتابخانه androidx.webkit بااستفاده از روش WebSettingsCompat.setWebAuthenticationSupport کنترل کامل این ادغام را به شما می‌دهد. می‌توانید از این روش برای پیکربندی سطح پشتیبانی موردنیاز برنامه‌تان استفاده کنید.

  • بهبود عملکرد: عملکرد WebView را بااستفاده از میاناهای برنامه‌سازی کاربردی مانند setBackForwardCacheEnabled تنظیم دقیق کنید یا بااستفاده از میاناهای برنامه‌سازی کاربردی بارگیری حدسی مانند prefetchUrlAsync و prerenderUrlAsync، تأخیر پیمایش را کاهش دهید. برای اطلاعات بیشتر، به بار کردن حدسی در WebView مراجعه کنید.

  • افزایش پایداری: بازیابی فرایندهای پردازشگر متوقف‌شده یا غیرپاسخگو بدون ازکار افتادن. برای اطلاعات بیشتر، به WebViewRenderProcess#terminate مراجعه کنید.

  • کنترل جزئی روی داده‌های مرور ارائه می‌دهد: برای حذف داده‌های مرور ذخیره‌شده توسط WebView برای مبدأهای خاص، از کلاس WebStorageCompat استفاده کنید.

  • پیمایش صفحه بهبودیافته ارائه می‌دهد: WebView.loadUrl را با WebViewCompat.navigate جایگزین کنید تا کنترل پیمایش دقیق، جایگزینی ورودی سابقه، پشتیبانی از سرصفحه وضعیت ذخیره‌شده، و ردیابی چرخه حیات مرتبط بااستفاده از NavigationListener را داشته باشید. برای اطلاعات بیشتر، ناوبری بهبودیافته صفحه با WebViewCompat.navigate را ببینید.

  • مدیریت وضعیت را بهینه‌سازی می‌کند: با تنظیم حداکثر محدودیت بایت درطول سریال‌سازی وضعیت، از TransactionTooLargeException محافظت می‌کند. برای اطلاعات بیشتر، به مدیریت کارآمد وضعیت WebView مراجعه کنید.

آشنایی با مؤلفه‌ها

برای استفاده مؤثر از Jetpack Webkit، باید رابطه بین مؤلفه‌های زیر را درک کنید:

  • Android System WebView: این موتور پردازشی مبتنی بر Chromium است که Google به‌طور منظم ازطریق «فروشگاه Google Play» با همان آهنگ Chrome به‌روز می‌کند. این مؤلفه حاوی به‌روزترین ویژگی‌ها است و کد پیاده‌سازی زیربنایی را برای همه میاناهای برنامه‌سازی کاربردی «وب‌نما» ارائه می‌دهد.

  • میاناهای برنامه‌سازی کاربردی چارچوب (android.webkit): این میاناهای برنامه‌سازی کاربردی برای نسخه خاصی از سیستم‌عامل Android ثابت هستند. برای مثال، برنامه‌ای در Android 10 فقط می‌تواند به میاناهای برنامه‌سازی کاربردی‌ای دسترسی داشته باشد که هنگام انتشار آن نسخه دردسترس بوده‌اند. بنابراین، نمی‌تواند از ویژگی‌های جدیدی که در به‌روزرسانی‌های جدیدتر به WebView APK اضافه شده است استفاده کند. برای مثال، برای دریافت دستگیره برای پردازنده غیرپاسخگو با WebView#getWebViewRenderProcess()، فقط می‌توانید این را در Android نسخه ۱۰ و بالاتر فراخوانی کنید.

  • کتابخانه Jetpack Webkit‏ (androidx.webkit): این کتابخانه کوچکی است که در برنامه‌تان گنجانده شده است. این کتابخانه به‌عنوان پلی عمل می‌کند که به‌جای فراخوانی میاناهای برنامه‌سازی کاربردی تعریف‌شده در پلاتفرم Android که نسخه سیستم‌عامل ثابتی دارد، WebView APK را فراخوانی می‌کند. به‌این‌ترتیب، حتی وقتی برنامه‌ای در دستگاهی با نسخه قدیمی‌تر سیستم‌عامل مثل Android 10 نصب شده باشد، برنامه می‌تواند از جدیدترین ویژگی‌های WebView استفاده کند. برای مثال، WebViewCompat.getWebViewRenderProcess() شبیه Framework API کار می‌کند، با این تفاوت که این مورد را می‌توان در همه نسخه‌های سیستم‌عامل قبل‌از Android 10 نیز فراخوانی کرد.

اگر میانای برنامه‌سازی کاربردی هم در چارچوب و هم در Jetpack Webkit دردسترس باشد، توصیه می‌کنیم نسخه Jetpack Webkit را انتخاب کنید. این کار به تضمین رفتار و سازگاری یکسان در گسترده‌ترین طیف دستگاه‌ها کمک می‌کند.

تعامل Jetpack Webkit و APK

میاناهای برنامه‌سازی کاربردی در Jetpack Webkit در دو بخش پیاده‌سازی می‌شوند:

  • Static Jetpack Webkit: کتابخانه Static Jetpack Webkit حاوی بخش کوچکی از کد مسئول پیاده‌سازی میانای برنامه‌سازی کاربردی است.

  • WebView APK: WebView APK حاوی بیشتر کدها است.

برنامه شما Jetpack Webkit API را فراخوانی می‌کند، که سپس WebView APK را فراخوانی می‌کند.

درحالی‌که نسخه Jetpack Webkit را در برنامه‌تان کنترل می‌کنید، نمی‌توانید به‌روزرسانی‌های WebView APK را در دستگاه‌های کاربران کنترل کنید. به‌طور کلی، اکثر کاربران نسخه‌های به‌روز WebView APK را دارند، اما برنامه شما همچنان باید مراقب باشد که میاناهای برنامه‌سازی کاربردی‌ای را که آن نسخه خاص WebView APK پشتیبانی نمی‌کند فراخوانی نکند.

Jetpack Webkit همچنین نیاز به بررسی دستی نسخه‌های «وب‌نما» را ازبین می‌برد. برای تعیین اینکه آیا ویژگی‌ای دردسترس است یا نه، ثابت ویژگی آن را بررسی کنید. برای مثال، WebViewFeature.WEB_AUTHENTICATION.

نحوه کارکرد آن‌ها با یکدیگر

‫Jetpack Webkit شکاف بین Framework API ثابت و WebView APK را که به‌طور مکرر به‌روز می‌شود پر می‌کند. وقتی از Jetpack Webkit API با الگوی تشخیص ویژگی استفاده می‌کنید، کتابخانه بررسی می‌کند که آیا این ویژگی توسط WebView APK نصب‌شده در دستگاه کاربر پشتیبانی می‌شود یا نه. این کار این مزیت را دارد که دیگر نیازی به بررسی نسخه سیستم‌عامل Android (چارچوب) نیست.

اگر WebView APK نسخه به‌اندازه کافی جدیدی باشد، کتابخانه ویژگی را فراخوانی می‌کند. اگر نه، گزارش می‌دهد که این ویژگی دردسترس نیست، از خراب شدن برنامه‌تان جلوگیری می‌کند، و به شما امکان می‌دهد وضعیت را به‌خوبی مدیریت کنید.

مقایسه میاناهای برنامه‌سازی کاربردی 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

هیچ API مستقیمی برای پاک کردن داده‌های منبع خاصی وجود ندارد. اغلب لازم است همه داده‌ها پاک شود.

با Jetpack WebKit

از میاناهای برنامه‌سازی کاربردی سازگاری برای حذف دقیق داده‌ها استفاده می‌کند. می‌توانید از یکی از گزینه‌های زیر استفاده کنید:

WebStorageCompat.getInstance().deleteBrowsingData()

یا

WebStorageCompat.getInstance().deleteBrowsingDataForSite()

دریافت نسخه «وب‌نما»

بدون 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 API به شما امکان می‌دهد محدودیت‌های بایت را اعمال کنید و سابقه جلو رفتن را درطول سریال‌سازی هرس کنید، که این کار از خرابی‌های TransactionTooLargeException جلوگیری می‌کند و درعین‌حال سابقه پیمایش ضروری را حفظ می‌کند.

بدون Jetpack WebKit

از روش چارچوب استاندارد استفاده می‌کند که کل پشته پیمایش را بدون محدودیت اندازه سریال‌سازی می‌کند و اگر بار خالص از حد تراکنش ۱ مگابایتی Android فراتر رود، می‌تواند TransactionTooLargeException را راه‌اندازی کند.

webView.saveState(outState)

با Jetpack WebKit

از WebViewCompat برای اعمال حداکثر محدودیت بایت یا حذف ورودی‌های پیمایش روبه‌جلو استفاده می‌کند و از سرریز تراکنش محافظت می‌کند.

WebViewCompat.saveState(webView, outState, maxSizeBytes)

برای اطلاعات بیشتر، به مدیریت کارآمد وضعیت WebView مراجعه کنید.

برای پیمایش صفحه‌های وب با پشتیبانی از جایگزینی ورودی سابقه، پشتیبانی از سرصفحه حالت ذخیره‌شده، و فراخوانی‌های چرخه حیات مرتبط، به‌جای WebView.loadUrl از WebViewCompat.navigate استفاده کنید.

بدون 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 قابلیت‌های کلاس استاندارد «وب‌نما» را تقویت می‌کند، اما به‌طور کامل جایگزین کلاس اصلی «وب‌نما» نمی‌شود.

می‌توانید همچنان از کلاس android.webkit.WebView استفاده کنید. می‌توانید آن را به چیدمان‌های XML خود اضافه کنید و مرجعی به نمونه در کد خود دریافت کنید. برای دسترسی به ویژگی‌های چارچوب استاندارد، همچنان می‌توانید روش‌ها را مستقیماً در نمونه WebView یا شیء تنظیمات آن فراخوانی کنید.

برای دسترسی به ویژگی‌های مدرن، از روش‌های کمکی ثابتی که Jetpack Webkit ارائه می‌دهد، مانند WebViewCompat و WebSettingsCompat، استفاده می‌کنید. نمونه WebView موجودتان را به این روش‌ها منتقل می‌کنید.

کاتلین

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)
}

جاوا

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، از روال زیر استفاده کنید.

مرحله ۱: افزودن وابستگی

در فایل build.gradle.kts یا build.gradle واحدتان، وابستگی زیر را برای افزودن Jetpack Webkit اضافه کنید:

شیار

dependencies {
    implementation "androidx.webkit:webkit:1.17.1"
}

کاتلین

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

Jetpack Webkit حاوی پوشاننده‌های نازک است، بنابراین تأثیر آن بر اندازه برنامه شما حداقل است.

مرحله ۲: اتخاذ الگوی تشخیص ویژگی

برای جلوگیری از ازکارافتادن هنگام فراخوانی میاناهای برنامه‌سازی کاربردی غیرقابل‌دسترس، از بررسی‌های ویژگی استفاده کنید. توصیه می‌کنیم هر فراخوانی میانای برنامه‌سازی کاربردی را با بررسی ویژگی احاطه کنید و احتمالاً منطق جایگزین را برای زمانی که میانای برنامه‌سازی کاربردی دردسترس نیست درنظر بگیرید.

الگوی زیر را برای استفاده از میانای برنامه‌سازی کاربردی وب‌نمای مدرن توصیه می‌کنیم:

کاتلین

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.
}

جاوا

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 ناچیز است.