В этом руководстве описываются преимущества библиотеки Jetpack Webkit, объясняется, как она работает и как вы можете реализовать ее в своих проектах.
Обзор
Компоненты WebView – важная часть разработки для Android, но иногда ими сложно управлять из-за несоответствия функций в разных версиях ОС Android. Каждая версия ОС Android предоставляет фиксированный набор API WebView. Поскольку Android обновляется реже, чем WebView, API Android могут не поддерживать все доступные функции WebView. Это приводит к замедлению внедрения функций и увеличению затрат на тестирование.
Jetpack Webkit решает эти проблемы, действуя как уровень совместимости и используя актуальный APK-файл WebView на устройстве пользователя. Кроме того, в ней есть новые современные API, доступные только в этой библиотеке.
Зачем использовать Jetpack Webkit?
Помимо совместимости с разными версиями, Jetpack Webkit также предлагает новые современные API, которые могут упростить разработку и улучшить функциональность приложения:
Поддержка современных методов аутентификации. WebView поддерживает современные стандарты веб-аутентификации, такие как WebAuthn, что позволяет использовать ключи доступа для входа. Библиотека
androidx.webkitпозволяет полностью контролировать интеграцию с помощью методаWebSettingsCompat.setWebAuthenticationSupport, который можно использовать для настройки уровня поддержки, необходимого вашему приложению.Повышение производительности. Вы можете оптимизировать производительность WebView с помощью таких API, как
setBackForwardCacheEnabled, или сократить задержку навигации, используя API упреждающей загрузки, например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. Она содержит самые современные функции и предоставляет базовый код реализации для всех API WebView.
Framework API (
android.webkit). Эти API привязаны к определенной версии ОС Android. Например, приложение на Android 10 может получить доступ только к тем API, которые были доступны на момент выпуска этой версии. Поэтому в нем нельзя использовать новые функции, добавленные в APK-файл WebView в более поздних обновлениях. Например, чтобы получить дескриптор неотвечающего средства визуализации с помощьюWebView#getWebViewRenderProcess(), вы можете вызвать его только на Android 10 и более поздних версиях.Библиотека Jetpack Webkit (
androidx.webkit). Это небольшая библиотека, которая входит в состав приложения. Эта библиотека выступает в качестве моста, который вызывает APK-файл WebView, а не API, определенные в платформе Android, у которой фиксированная версия ОС. Таким образом, даже если приложение установлено на устройстве со старой версией ОС, например Android 10, оно может использовать новейшие функции WebView. Например,WebViewCompat.getWebViewRenderProcess()работает аналогично Framework API, но может вызываться на всех версиях ОС до Android 10.
Если API доступен как в фреймворке, так и в Jetpack Webkit, мы рекомендуем выбрать версию Jetpack Webkit. Это помогает обеспечить стабильную работу и совместимость с максимально широким спектром устройств.
Взаимодействие Jetpack Webkit и APK
API в Jetpack Webkit реализованы в двух частях:
Статическая библиотека Jetpack Webkit содержит небольшую часть кода, отвечающего за реализацию API.
WebView APK. Содержит большую часть кода.
Приложение вызывает Jetpack Webkit API, который затем вызывает WebView APK.
Вы можете управлять версией Jetpack Webkit в своем приложении, но не можете контролировать обновления APK-файла WebView на устройствах пользователей. Как правило, у большинства пользователей установлены актуальные версии WebView APK, но в приложении все равно не следует вызывать API, которые не поддерживаются в определенной версии WebView APK.
Jetpack Webkit также избавляет от необходимости вручную проверять версии WebView.
Чтобы определить, доступна ли функция, проверьте ее константу. Пример: WebViewFeature.WEB_AUTHENTICATION.
Принцип работы
Jetpack Webkit устраняет разрыв между статическим Framework API и часто обновляемым WebView APK. Когда вы используете Jetpack Webkit API с шаблоном обнаружения функций, библиотека проверяет, поддерживается ли функция APK-файлом WebView, установленным на устройстве пользователя. Это позволяет не проверять версию ОС Android (фреймворка).
Если версия APK-файла WebView достаточно новая, библиотека вызывает функцию. Если нет, то сообщает, что функция недоступна, предотвращая сбой приложения и позволяя вам корректно обработать ситуацию.
Сравнение Jetpack Webkit и Framework API
В этом разделе сравниваются методы реализации с библиотекой Jetpack Webkit и без нее.
Включить современную аутентификацию (WebAuthn)
Без Jetpack Webkit
Невозможно через API фреймворка.
С помощью 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
Использует API совместимости для точного удаления данных. Вы можете использовать один из следующих вариантов:
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… Подробную информацию об API вы можете найти в androidx.webkit
справочной документации.
Управление сохраненным состоянием и размером транзакции
API WebViewCompat.saveState позволяет устанавливать ограничения на размер в байтах и удалять историю переходов вперед во время сериализации, предотвращая сбои TransactionTooLargeException и сохраняя важную историю навигации.
Без Jetpack WebKit
Использует стандартный метод фреймворка, который сериализует весь стек навигации без ограничений по размеру и может вызвать ошибку TransactionTooLargeException, если полезная нагрузка превышает лимит транзакций Android в 1 МБ.
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, но не заменяет его полностью.
Вы можете продолжать использовать класс 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. Добавьте зависимость
Чтобы добавить Jetpack Webkit, включите в файл build.gradle.kts или build.gradle модуля следующую зависимость:
классный
dependencies { implementation "androidx.webkit:webkit:1.17.1" }
Котлин
dependencies { implementation("androidx.webkit:webkit:1.17.1") }
Jetpack Webkit содержит тонкие оболочки, поэтому влияние на размер вашего приложения минимально.
Шаг 2. Используйте шаблон обнаружения функций
Чтобы избежать сбоев при вызове недоступных API, используйте проверки функций. Рекомендуем окружать каждый вызов API проверкой функций и, возможно, использовать резервную логику на случай, если API недоступен.
Мы рекомендуем использовать современный WebView API следующим образом:
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 практически не влияет на производительность.