Общая информация о Play Feature Delivery

Модель распространения приложений в Google Play использует наборы Android App Bundle, чтобы создавать и предоставлять оптимизированные APK-файлы для конфигурации устройства каждого пользователя. Таким образом, пользователи скачивают только код и ресурсы, необходимые для запуска приложения.

Play Feature Delivery использует расширенные возможности наборов App Bundle, позволяя скачивать определенные функции приложения по запросу или при соблюдении заданных условий. Для этого сначала нужно отделить эти функции от основного приложения и поместить их в модули функций.

Конфигурация сборки модуля функции

Когда вы создаете новый модуль функции в Android Studio, IDE применяет следующий плагин Gradle к файлу build.gradle модуля.

// The following applies the dynamic-feature plugin to your feature module.
// The plugin includes the Gradle tasks and properties required to configure and build
// an app bundle that includes your feature module.

plugins {
  id 'com.android.dynamic-feature'
}

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

Что не следует включать в конфигурацию сборки модуля функции

Поскольку каждый модуль функции зависит от основного модуля, он также наследует определенные конфигурации. Поэтому в файле build.gradle модуля функции не должно быть следующих строк:

  • Конфигурации подписи. Наборы App Bundle подписываются с помощью конфигураций подписи, которые вы указываете в основном модуле.
  • Свойство minifyEnabled. Вы можете включить сокращение кода для всего проекта приложения в конфигурации сборки базового модуля. Поэтому не следует включать это свойство в модули функций. Однако вы можете указать дополнительные правила ProGuard для каждого модуля функции.
  • versionCode и versionName. При создании набора App Bundle Gradle использует информацию о версии приложения, которую предоставляет основной модуль. Удалите эти свойства из файла build.gradle модуля функции.

Установите связь с базовым модулем

Когда Android Studio создает модуль функции, он становится видимым для основного модуля, поскольку в файл build.gradle основного модуля добавляется свойство android.dynamicFeatures, как показано ниже:

// In the base module’s build.gradle file.
android {
    ...
    // Specifies feature modules that have a dependency on
    // this base module.
    dynamicFeatures = [":dynamic_feature", ":dynamic_feature2"]
}

Кроме того, Android Studio включает базовый модуль в качестве зависимости модуля функции, как показано ниже:

// In the feature module’s build.gradle file:
...
dependencies {
    ...
    // Declares a dependency on the base module, ':app'.
    implementation project(':app')
}

Укажите дополнительные правила ProGuard

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

android.buildTypes {
     release {
         // You must use the following property to specify additional ProGuard
         // rules for feature modules.
         proguardFiles 'proguard-rules-dynamic-features.pro'
     }
}

Обратите внимание, что эти правила ProGuard объединяются с правилами из других модулей (включая базовый) во время сборки. Таким образом, хотя в каждом модуле функций может быть указан новый набор правил, эти правила применяются ко всем модулям в проекте приложения.

Как опубликовать приложение

При разработке приложения с поддержкой модулей функций вы можете развернуть его на подключенном устройстве обычным способом, выбрав в строке меню Run (Запустить) > Run (Запустить) или нажав Run (Запустить) на панели инструментов.

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

  1. В строке меню выберите Run (Выполнить) > Edit Configurations (Изменить конфигурации).
  2. На левой панели диалогового окна Run/Debug Configurations (Конфигурации выполнения/отладки) выберите нужную конфигурацию Android App (Приложение Android).
  3. На вкладке General (Общие) в разделе Dynamic features to deploy (Динамические функции для развертывания) установите флажки рядом с модулями функций, которые нужно включить при развертывании приложения.
  4. Нажмите ОК.

По умолчанию Android Studio не использует наборы App Bundle для развертывания приложения. Вместо этого IDE создает и устанавливает на устройство APK-файлы, оптимизированные для скорости развертывания, а не для размера APK. Чтобы настроить Android Studio для создания и развертывания APK-файлов и приложений с мгновенным запуском из набора App Bundle, измените конфигурацию выполнения/отладки.

Как использовать модули функций для выборочной доставки

Уникальное преимущество модулей функций – возможность настраивать, как и когда различные функции приложения скачиваются на устройства с Android 5.0 (уровень API 21) или более поздней версии. Например, чтобы уменьшить размер приложения при скачивании, вы можете настроить загрузку некоторых функций по запросу или только на устройства, которые поддерживают определенные возможности, такие как фотосъемка или дополненная реальность.

При загрузке приложения в виде набора App Bundle вы по умолчанию получаете оптимизированные скачиваемые файлы. Однако для более продвинутых и настраиваемых вариантов доставки функций требуется дополнительная настройка и модульное разделение функций приложения с помощью модулей функций. Другими словами, модули функций – это строительные блоки для создания модульных функций, которые можно настроить для скачивания по мере необходимости.

Предположим, что у вас есть приложение, которое позволяет пользователям покупать и продавать товары на онлайн-площадке. Вы можете выделить в отдельные модули следующие функции приложения:

  • Вход в аккаунт и его создание
  • Просмотр торговой площадки
  • Выставление товара на продажу
  • Обработка платежей

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

Способ доставки Поведение Пример использования Начало работы
Доставка при установке Модули функций, для которых не настроены описанные выше варианты доставки, по умолчанию скачиваются при установке приложения. Это важная особенность, поскольку она позволяет постепенно внедрять расширенные варианты доставки. Например, вы можете разделить функции приложения на модули и включить доставку по запросу только после того, как полностью реализуете скачивание по запросу с помощью библиотеки Play Feature Delivery.

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

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

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

Разбейте приложение на модули, не настраивая расширенные варианты доставки.

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

Доставка по запросу Позволяет приложению запрашивать и скачивать модули функций по мере необходимости. Если только 20% пользователей торговой площадки размещают товары на продажу, то хорошей стратегией для уменьшения размера приложения при первоначальном скачивании будет сделать функции фотографирования, добавления описания и размещения товара доступными для скачивания по запросу. Например, модуль функции для продажи в приложении можно скачивать только тогда, когда пользователь проявляет интерес к размещению товаров на торговой площадке.

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

Создайте модуль функции и настройте доставку по запросу. Затем приложение может использовать библиотеку Play Feature Delivery, чтобы запрашивать скачивание модуля по требованию.
Условная доставка Позволяет задать требования к устройствам пользователей, например аппаратные характеристики, языковые стандарты и минимальный уровень API, чтобы определить, будет ли скачиваться модульная функция при установке приложения. Если приложение торговой площадки имеет глобальный охват, вам может потребоваться поддержка способов оплаты, популярных только в определенных регионах или населенных пунктах. Чтобы уменьшить размер приложения при скачивании, вы можете создать отдельные модули функций для обработки определенных типов способов оплаты и настроить их условную установку на устройство пользователя в зависимости от зарегистрированного региона. Создайте модуль функции и настройте условную доставку.
Мгновенная доставка Google Play Instant позволяет пользователям взаимодействовать с вашим приложением без его установки на устройство. Вместо этого они могут запустить приложение с мгновенным запуском, нажав кнопку "Попробовать" в Google Play или перейдя по созданной вами ссылке. Такой способ доставки контента позволяет повысить вовлеченность пользователей.

Google Play Instant позволяет пользователям сразу же опробовать некоторые функции вашего приложения без установки.

Предположим, что в игре есть модуль функции, который содержит первые несколько уровней. Вы можете включить мгновенный запуск для этого модуля, чтобы пользователи могли сразу начать играть, перейдя по ссылке или нажав кнопку "Попробовать", без установки приложения. Создайте модуль функции и настройте мгновенную доставку. Затем приложение может использовать библиотеку Play Feature Delivery, чтобы запрашивать скачивание модуля по требованию.

Помните, что разбиение функций приложения на модули – это только первый шаг. Чтобы поддерживать Google Play Instant, размер скачиваемого основного модуля приложения и определенной функции с мгновенным запуском должен соответствовать строгим ограничениям. Подробнее о том, как уменьшить размер приложения или игры, чтобы включить мгновенный запуск…

Как создать URI для ресурса

Если вы хотите получить доступ к ресурсу, хранящемуся в модуле функции, с помощью URI, вот как сгенерировать URI ресурса модуля функции с помощью Uri.Builder():

Kotlin

val uri = Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
                .appendPath(resources.getResourceTypeName(resId))
                .appendPath(String.format("%s:%s",
                  resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
                  resources.getResourceEntryName(resId)
                  ))
                .build()

Java

String uri = Uri.Builder()
                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                .authority(context.getPackageName()) // Look up the resources in the application with its splits loaded
                .appendPath(resources.getResourceTypeName(resId))
                .appendPath(String.format("%s:%s",
                  resources.getResourcePackageName(resId), // Look up the dynamic resource in the split namespace.
                  resources.getResourceEntryName(resId)
                  ))
                .build().toString();

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

Предположим, у вас есть приложение и модули функций со следующими названиями:

  • Название пакета приложения: com.example.my_app_package
  • Название пакета ресурсов функции: com.example.my_app_package.my_dynamic_feature

Если resId в приведенном выше фрагменте кода относится к необработанному файловому ресурсу с названием my_video в модуле функции, то код Uri.Builder() выведет следующее:

android.resource://com.example.my_app_package/raw/com.example.my_app_package.my_dynamic_feature:my_video

Затем приложение может использовать этот URI для доступа к ресурсу модуля функции.

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

Скриншот APK Analyzer, проверяющего содержимое скомпилированного файла ресурсов.
Рисунок 1. Чтобы проверить название пакета в скомпилированном файле ресурсов, используйте APK Analyzer.

Что нужно учитывать при работе с модулями функций

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

  • Установка 50 или более модулей функций на одном устройстве с помощью условной доставки или доставки по запросу может привести к проблемам производительности. Модули, устанавливаемые при скачивании и не настроенные как удаляемые, автоматически включаются в базовый модуль и считаются как один модуль функции на каждом устройстве.
  • Ограничьте количество модулей, которые вы настраиваете как удаляемые для доставки при установке, до 10 или меньше. В противном случае время скачивания и установки приложения может увеличиться.
  • Скачивание и установка функций по запросу поддерживаются только на устройствах с Android 5.0 (уровень API 21) и более поздними версиями. Чтобы функция была доступна в более ранних версиях Android, включите объединение при создании модуля функции.
  • Включите SplitCompat, чтобы у приложения был доступ к скачанным модулям функций, которые доставляются по запросу.
  • В манифесте модулей функций не должно быть действий, для которых свойство android:exported имеет значение true. Это связано с тем, что нет гарантии, что устройство скачало модуль функции, когда другое приложение пытается запустить действие. Кроме того, перед попыткой доступа к коду и ресурсам функции приложение должно подтвердить, что она скачана. Подробнее о том, как управлять установленными модулями…
  • Поскольку для Play Feature Delivery требуется публиковать приложение в виде набора App Bundle, ознакомьтесь с известными проблемами, которые могут возникнуть при работе с такими наборами.

Справочная информация о манифесте модуля функции

При создании нового модуля функции в Android Studio интегрированная среда разработки включает большинство атрибутов манифеста, необходимых для работы модуля функции. Кроме того, некоторые атрибуты добавляются системой сборки во время компиляции, поэтому вам не нужно указывать или изменять их самостоятельно. В таблице ниже описаны атрибуты манифеста, которые важны для модулей функций.

Атрибут Описание
<manifest Это типичный блок <manifest>.
xmlns:dist="http://schemas.android.com/apk/distribution" Указывает новое пространство имен XML dist:, которое описано ниже.
split="split_name" Когда Android Studio создает набор App Bundle, этот атрибут добавляется автоматически. Поэтому не добавляйте и не изменяйте этот атрибут самостоятельно.

Определяет название модуля, которое приложение указывает при запросе модуля по запросу с помощью библиотеки Play Feature Delivery.

Как Gradle определяет значение этого атрибута:

По умолчанию при создании модуля функции в Android Studio интегрированная среда разработки использует значение, указанное в поле Module name (Название модуля), чтобы идентифицировать модуль как подпроект Gradle в файле настроек Gradle.

При сборке набора App Bundle Gradle использует последний элемент пути подпроекта, чтобы вставить этот атрибут манифеста в манифест модуля. Например, если вы создаете новый модуль функции в каталоге MyAppProject/features/ и указываете dynamic_feature1 в качестве названия модуля, IDE добавляет ':features:dynamic_feature1' как подпроект в файл settings.gradle. При создании набора App Bundle Gradle добавляет <manifest split="dynamic_feature1"> в манифест модуля.

android:isFeatureSplit="true | false"> Когда Android Studio создает набор App Bundle, этот атрибут добавляется автоматически. Поэтому не нужно добавлять или изменять этот атрибут вручную.

Указывает, что этот модуль является модулем функции. В манифестах базового модуля и APK-файлов конфигурации этот атрибут либо отсутствует, либо имеет значение false.

<dist:module Определяет атрибуты, которые задают способ упаковки и распространения модуля в виде APK.
dist:instant="true | false" Указывает, должен ли модуль быть доступен в Google Play Instant как приложение с мгновенным запуском.

Если в приложении есть один или несколько модулей функций с мгновенным запуском, вы должны включить мгновенный запуск и для основного модуля. Если вы используете Android Studio 3.5 или более поздней версии, интегрированная среда разработки сделает это за вас, когда вы создадите модуль функции с мгновенным запуском.

Нельзя одновременно задать для этого элемента XML значение true и указать <dist:on-demand/>. Однако вы можете запрашивать скачивание модулей функций с мгновенным запуском в виде приложений с мгновенным запуском с помощью библиотеки Play Feature Delivery. Когда пользователь скачивает и устанавливает приложение, на устройство по умолчанию загружаются и устанавливаются модули функций с мгновенным запуском, а также основной APK-файл.

dist:title="@string/feature_name"> Указывает пользовательское название модуля. Например, устройство может показывать это название, когда запрашивает подтверждение скачивания.

Вам нужно добавить строковый ресурс для этого названия в файл module_root/src/source_set/res/values/strings.xml основного модуля.

<dist:fusing dist:include="true | false" /> Указывает, нужно ли включать модуль в мульти-APK, предназначенные для устройств с Android 4.4 (уровень API 20) и более ранних версий.

Кроме того, когда вы используете bundletool для создания APK-файлов из набора App Bundle, в универсальный APK-файл (монолитный APK-файл, который включает код и ресурсы для всех конфигураций устройств, поддерживаемых вашим приложением) добавляются только модули функций, для которых это свойство имеет значение true.

<dist:delivery> Инкапсулирует параметры, которые настраивают доставку модуля, как показано ниже. Помните, что в каждом модуле функции можно настроить только один тип доставки.
<dist:install-time> Указывает, что модуль должен быть доступен во время установки. Это режим работы по умолчанию для модулей функций, в которых не указан другой тип доставки.

Подробнее о скачивании при установке…

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

<dist:removable dist:value="true | false" />

Если значение не задано или установлено как false, bundletool объединит модули, устанавливаемые при скачивании, с базовым модулем при создании раздельных APK из набора. Поскольку в результате объединения раздельных APK станет меньше, эта настройка может повысить производительность приложения.

Если для параметра removable задано значение true, модули, устанавливаемые при скачивании, не будут объединены с базовым модулем. Если вы хотите удалить модули в будущем, задайте значение true. Однако если вы сделаете удаляемыми слишком много модулей, это может увеличить время установки приложения.

Значение по умолчанию – false. Указывать это значение в манифесте нужно, только если вы хотите отключить объединение для модуля функции.

Примечание. Эта функция доступна только при использовании плагина Android Gradle версии 4.2 или bundletool версии 1.0 из командной строки.

</dist:install-time>  
<dist:on-demand /> Указывает, что модуль должен быть доступен для скачивания по запросу. Это значит, что модуль недоступен во время установки, но приложение может запросить его скачивание позже.

Подробнее о скачивании по запросу…

</dist:delivery>
</dist:module>
<application
android:hasCode="true | false">
...
</application>
Если модуль функции не генерирует DEX-файлы, то есть не содержит кода, который позже компилируется в формат DEX, необходимо выполнить следующие действия (в противном случае могут возникнуть ошибки выполнения):
  1. В манифесте модуля функции задайте для параметра android:hasCode значение "false".
  2. Добавьте в манифест базового модуля следующий код:
    <application
      android:hasCode="true"
      tools:replace="android:hasCode">
      ...
    </application>
...
</manifest>

Дополнительные ресурсы

Дополнительную информацию о модулях функций можно найти по ссылкам ниже.

Записи в блоге

Видео

Условия использования и безопасность данных

Получая доступ к библиотеке Play Feature Delivery или используя ее, вы принимаете Условия использования пакета средств разработки Play Core. Прежде чем начать работу с библиотекой, ознакомьтесь со всеми действующими условиями и правилами.

Безопасность данных

Библиотеки Play Core – это интерфейс среды выполнения приложения, который связывает его с Google Play. Когда вы используете Play Core в своем приложении, Google Play запускает собственные процессы, в том числе обработку данных, которая регулируется Условиями использования Google Play. Ниже описано, как библиотеки Play Core обрабатывают данные, чтобы выполнять определенные запросы из вашего приложения.

API дополнительных языков

Данные, собираемые при использовании Список установленных языков
Цель сбора данных Собранные данные используются для предоставления версий приложения на разных языках и сохранения установленных языков после обновления приложения.
Шифрование данных Данные зашифрованы.
Передача данных Данные не передаются третьим лицам.
Удаление данных Данные удаляются по истечении фиксированного срока хранения.

Play Feature Delivery

Данные, собираемые при использовании Метаданные устройства
Версия приложения
Цель сбора данных Собранные данные используются для того, чтобы предоставлять устройству нужный модуль и сохранять установленные модули после обновления, резервного копирования и восстановления.
Шифрование данных Данные зашифрованы.
Передача данных Данные не передаются третьим лицам.
Удаление данных Данные удаляются по истечении фиксированного срока хранения.

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