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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Помните, что модуляризация функций вашего приложения с помощью модулей функций — это только первый шаг. Для поддержки 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 использует последний элемент пути подпроекта для внедрения этого атрибута manifest в манифест модуля. Например, если вы создаете новый модуль функций в каталоге MyAppProject/features/ и указываете "dynamic_feature1" в качестве имени модуля , IDE добавляет ':features:dynamic_feature1' в качестве подпроекта в ваш файл settings.gradle . При создании пакета приложений Gradle затем внедряет <manifest split="dynamic_feature1"> в манифест модуля.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

По умолчанию false . Это значение необходимо задать в манифесте только в том случае, если вы хотите отключить объединение для функционального модуля.

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

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

Чтобы узнать больше о загрузках по требованию, прочитайте раздел Настройка доставки по требованию .

</dist:доставка>
</расстояние:модуль>
<приложение
android:hasCode = "истина | ложь">
...
</приложение>
Если функциональный модуль не генерирует файлы 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 относительно сбора, передачи и мер безопасности пользовательских данных вашего приложения.