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

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

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

  • Плагин Android Gradle (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. Скопируйте ресурсы SDK Java в SDK, разделенный как ресурсы.
  3. Пересопоставьте ресурсы SDK и объедините их с ресурсами приложения.
  4. Создайте конфигурации для клиентской библиотеки среды выполнения SDK.

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

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

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

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

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

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

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

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

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

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

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

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

среда SDK

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

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

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

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

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

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

Ресурсы SDK

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

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

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

Ресурсы Java

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

Ресурсы SDK

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

SDK-хранилище

Для поддержки хранилища SDK библиотека клиента среды выполнения SDK создает выделенный корневой каталог для каждого связанного 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 предоставляет реализацию SdkSandboxControllerCompat для связанных SDK, загружаемых в процесс приложения.

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

Управление версиями

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

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

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

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

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

{% дословно %} {% дословно %} {% дословно %} {% дословно %}