Обзор предоставления функций Play

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

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

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

При создании нового функционального модуля с помощью 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 функционального модуля следует исключить следующее:

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

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

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

// 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 объединяются с правилами других модулей (включая базовый) во время сборки. Таким образом, хотя каждый функциональный модуль может определять новый набор правил, эти правила применяются ко всем модулям в проекте приложения.

Разверните свое приложение

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

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

  1. В строке меню выберите Выполнить > Изменить конфигурации .
  2. На левой панели диалогового окна «Конфигурации запуска/отладки» выберите нужную конфигурацию приложения Android .
  3. В разделе Динамические функции для развертывания на вкладке Общие установите флажок рядом с каждым модулем функций, который вы хотите включить при развертывании приложения.
  4. Нажмите ОК .

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

Используйте функциональные модули для индивидуальной доставки

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Имейте в виду, что модуляризация функций вашего приложения с помощью модулей функций — это только первый шаг. Для поддержки Google Play Instant размер загружаемого базового модуля вашего приложения и соответствующей функции с поддержкой мгновенного запуска должен соответствовать строгим ограничениям. Подробнее см. в статье «Включение мгновенного запуска за счёт уменьшения размера приложения или игры» .

Создание URI для ресурса

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

Котлин

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

Ява

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-файлов.

В качестве примера того, как генерируется URI, предположим, что у вас есть приложение и функциональные модули с такими именами:

  • Имя пакета приложения: 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, включите функцию Fusing при создании модуля функции.
  • Включите SplitCompat , чтобы ваше приложение имело доступ к загруженным функциональным модулям, которые доставляются по требованию.
  • Модули функций не должны указывать действия в манифесте с android:exported установленным в значение true . Это связано с тем, что нет гарантии, что устройство загрузит модуль функции, когда другое приложение попытается запустить действие. Кроме того, ваше приложение должно подтвердить загрузку функции, прежде чем пытаться получить доступ к её коду и ресурсам. Подробнее см. в разделе Управление установленными модулями .
  • Поскольку Play Feature Delivery требует, чтобы ваше приложение было опубликовано с использованием пакета приложений, убедитесь, что вы осведомлены об известных проблемах пакета приложений.

Ссылка на манифест модуля функций

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

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

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

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

По умолчанию при создании модуля функции с помощью Android Studio среда IDE использует указанное вами имя модуля для идентификации модуля как подпроекта Gradle в файле настроек Gradle .

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

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

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

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

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

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

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

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

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

Кроме того, когда вы используете bundletool для генерации APK из пакета приложений , в универсальный 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 v1.0 из командной строки.

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

Дополнительную информацию о загрузках по требованию см. в разделе Настройка доставки по требованию .

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

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

Чтобы узнать больше об использовании функциональных модулей, попробуйте следующие ресурсы.

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

Видео

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

Получая доступ к библиотеке Play Feature Delivery Library или используя её, вы соглашаетесь с Условиями обслуживания Play Core Software Development Kit . Перед доступом к библиотеке, пожалуйста, ознакомьтесь со всеми применимыми условиями и политиками.

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

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

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

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

Доставка функций Play

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

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