Обратная совместимость для среды выполнения SDK

В этом документе предлагается новая библиотека Jetpack, призванная помочь разработчикам с миграцией на среду выполнения SDK . В нем объясняется, как будет поддерживаться среда выполнения SDK для предыдущих версий платформы Android (от сборки до выполнения), и какие различия или ограничения в среде выполнения могут ожидать разработчики. Эта библиотека позволяет разработчикам создавать единую версию своего приложения или SDK, которая включает возможность запуска на устройствах с поддержкой среды выполнения SDK или без нее.

Обратная совместимость обеспечивается за счет следующих компонентов:

  • Android Gradle Plugin (AGP) + Bundletool создает вариант приложения для устройств без поддержки среды выполнения SDK, включая среду выполнения SDK в APK-файл.

  • Клиентская библиотека среды выполнения SDK ( androidx.privacysandbox.sdkruntime:sdkruntime-client ) загружает встроенный SDK из ресурсов приложения и эмулирует среду выполнения SDK на устройствах, не поддерживающих среду выполнения SDK.

  • Библиотека поставщика среды выполнения SDK ( androidx.privacysandbox.sdkruntime:sdkruntime-provider ) предоставляет API для SDK, позволяющий загружать компоненты из клиентской библиотеки среды выполнения SDK.

Доставка SDK с помощью Bundletool

На устройствах с поддержкой SDK Runtime SDK будут поставляться и устанавливаться в виде отдельных пакетов.

Для поддержки версий платформы, в которых отсутствует поддержка среды выполнения SDK, Bundletool создаст один или несколько вариантов набора APK-файлов приложения, включающих все SDK, от которых зависит приложение. Каждый SDK упаковывается как отдельный APK-файл. Кроме того, выполняются следующие преобразования:

  1. Скопируйте файлы байт-кода SDK (DEX) в раздел SDK в качестве ресурсов.
  2. Скопируйте ресурсы Java SDK в раздел SDK в качестве ресурсов.
  3. Переназначьте ресурсы SDK и объедините их с ресурсами приложения.
  4. Сгенерировать конфигурационные файлы для клиентской библиотеки среды выполнения SDK.

Загрузка SDK с помощью клиентской библиотеки среды выполнения SDK.

Клиентская библиотека среды выполнения SDK предоставляет API, аналогичные API платформы, но поддерживает как SDK, входящие в среду выполнения SDK, так и SDK, поставляемые в комплекте с вариантом приложения.

Для использования клиентской библиотеки среды выполнения SDK добавьте зависимость androidx.privacysandbox.sdkruntime:sdkruntime-client и используйте SdkSandboxManagerCompat вместо SdkSandboxManager .

Когда приложение пытается загрузить SDK, библиотека сначала проверяет, был ли SDK включен в состав приложения во время сборки. Если да, библиотека извлекает SDK из разделенного пакета и загружает его в процесс приложения. Если SDK не был включен в состав приложения, библиотека передает загрузку SDK API платформы.

Извлечение SDK из ресурсов

Когда приложение пытается загрузить входящий в комплект SDK, клиентская библиотека среды выполнения SDK проверяет, были ли DEX-файлы SDK уже извлечены в память устройства ( code_cache ), и если нет, извлекает их из ресурсов.

Библиотека обычно извлекает файлы только один раз после установки или обновления приложения.

Если доступное место для хранения данных меньше допустимого порога (в настоящее время 100 МБ) и файлы DEX не извлечены, библиотека пытается загрузить SDK непосредственно из ресурсов на поддерживаемых устройствах (API 27+). Это приводит к увеличению объема используемой памяти.

Загрузчик классов для классов SDK

Во избежание конфликтов между SDK и классами приложения все классы SDK загружаются с помощью отдельного загрузчика классов, полностью независимого от основного загрузчика классов приложения.

В текущей архитектуре среды выполнения SDK все взаимодействия между приложением и SDK происходят с помощью вызовов межпроцессного взаимодействия Binder. Те же объекты SDK Binder используются для SDK, входящих в комплект поставки, а сериализация транзакций Binder позволяет разработчикам приложений преобразовывать объекты SDK Binder в интерфейсы SDK Binder на стороне приложения.

Для других внутренних взаимодействий (таких как инициализация SDK, предоставление API контроллера SDK и т. д.) библиотека использует рефлексию и динамические прокси для работы с различными загрузчиками классов.

среда SDK

Библиотека SDKRuntime Provider предоставляет разработчикам SDK API. Эти API аналогичны API платформы, но позволяют загружать SDK как средой выполнения SDK, так и клиентской библиотекой SDKRuntime.

Для использования библиотеки SDK необходимо добавить зависимость androidx.privacysandbox.sdkruntime:sdkruntime-provider и расширить SandboxedSdkProviderCompat вместо SandboxedSdkProvider .

Также необходимо использовать SandboxedSdkProviderAdapter в качестве поставщика SDK, чтобы обеспечить загрузку совместимого поставщика в среду выполнения SDK.

Функция SdkSandboxControllerCompat делегирует управление API платформы при загрузке SDK в среде выполнения SDK или библиотеке SDKRuntime Client при загрузке SDK в составе комплекта SDK.

Для входящих в комплект SDK библиотека изменяет среду SDK таким образом, чтобы имитировать поведение, аналогичное среде выполнения SDK.

В следующих разделах описывается ожидаемое поведение при загрузке SDK библиотекой SDKRuntime Client.

Ресурсы SDK

Ресурсы SDK (res/) поддерживаются при загрузке SDK в процессе приложения. Bundletool объединяет все ресурсы SDK с ресурсами приложения.

Во избежание конфликтов ресурсы SDK переназначаются путем изменения префикса packageId во всех идентификаторах ресурсов.

При загрузке SDK библиотекой SDKRuntime Client, packageId обновляется в среде выполнения, что позволяет обращаться к переназначенным ресурсам с помощью класса R.

Ресурсы Java

Поддержка ресурсов Java осуществляется при загрузке SDK в процессе приложения. Bundletool копирует все ресурсы Java из SDK в специальный каталог в папке ресурсов приложения. Клиентская библиотека SDKRuntime использует промежуточный загрузчик классов для перенаправления всех вызовов, связанных с ресурсами Java, в новый корневой каталог.

Ресурсы SDK

Ресурсы SDK объединяются с ресурсами приложения без переназначения.

Хранилище SDK

Для поддержки хранилища SDK библиотека SDK Runtime Client создает отдельный корневой каталог для каждого входящего в состав SDK в хранилище приложения и предоставляет специальный контекст, который использует этот каталог в качестве корневого каталога хранилища.

Этот контекст можно получить с помощью SandboxedSdkProviderCompat#getContext .

Поддерживаемые методы, связанные с хранением данных:

  • getDataDir
  • getCacheDir
  • getCodeCacheDir
  • getNoBackupFilesDir
  • getDir
  • getFilesDir
  • openFileInput
  • openFileOutput
  • deleteFile
  • getFileStreamPath
  • fileList
  • getDatabasePath
  • openOrCreateDatabase
  • moveDatabaseFrom - только между контекстами SDK
  • deleteDatabase
  • databaseList
  • getSharedPreferences
  • moveSharedPreferencesFrom - только между контекстами SDK
  • deleteSharedPreferences

Контекст защищенного хранилища устройства можно создать, вызвав метод createDeviceProtectedStorageContext() для этого контекста.

SdkSandboxControllerCompat

Библиотека SDKRuntime Client предоставляет реализацию SdkSandboxControllerCompat для SDK, загружаемых в процессе приложения.

Если API не поддерживаются клиентской библиотекой (например, в SDK, собранном с использованием версии библиотеки, более новой, чем версия приложения), будет использован наиболее подходящий резервный вариант (бездействие или исключение).

Версионирование

Когда библиотека SDKRuntime Client загружает входящий в комплект SDK, она выполняет процедуру установления соединения с библиотекой SDKRuntime Provider, находящейся внутри SDK. В ходе этой процедуры библиотеки обмениваются версиями и корректируют свое поведение, заменяя недоступные API наиболее подходящим резервным вариантом (бездействие или исключение).

Разработчикам приложений и SDK настоятельно рекомендуется использовать самую последнюю версию библиотеки, иначе функциональность, требующая поддержки в обеих частях, может быть недоступна.

Любая версия библиотеки SDKRuntime Client может загрузить SDK с любой версией библиотеки SDKRuntime Provider, и наоборот.

В будущем это будет изменено на минимальную версию клиентской библиотеки, необходимую для загрузки SDK с определенной версией библиотеки поставщика.

Это позволит свести к минимуму фрагментацию и поможет обеспечить поддержку большинства API при успешной загрузке входящего в комплект SDK.

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}