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

Модель обслуживания приложений Google Play использует пакеты приложений Android для создания и предоставления оптимизированных 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) или выше. Например, чтобы уменьшить первоначальный размер загрузки вашего приложения, вы можете настроить загрузку определенных функций либо по мере необходимости, либо только на устройствах, которые поддерживают определенные возможности, такие как возможность делать снимки или поддерживать функции дополненной реальности.

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

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

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

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

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

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

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

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

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

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

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

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

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

Благодаря мгновенной доставке вы можете использовать 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 для проверки APK вашего функционального модуля и определения имени пакета:

Скриншот APK-анализатора, проверяющего содержимое скомпилированного файла ресурсов.

Рисунок 2. Используйте анализатор APK для проверки имени пакета в скомпилированном файле ресурсов.

Рекомендации по функциональным модулям

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

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

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

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

Атрибут Описание
<manifest
...
Это типичный блок <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 Этот новый элемент XML определяет атрибуты, которые определяют, как модуль упаковывается и распространяется в виде APK.
dist:instant="true | false" Указывает, должен ли модуль быть доступен через Google Play Instant как мгновенный опыт.

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

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

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

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

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

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

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

Сообщения в блоге

Видео

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

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

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

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

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

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

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

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

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