Рассмотрим распространённую задачу: есть приложение, у которого есть две версии — ограниченная и полная. Они выпускаются с разными applicationId, у каждого своя иконка, и в ограниченной отсутствует некоторая функциональность.
Что будем делать?
Первая мысль: делаем в VCS две ветки, работаем в какой-то одной, а потом добавляем изменения в другую. Вполне себе выход. Правда, мержи постепенно превращаются в ад, так что лучше эту мысль сразу отбросить и решать проблему на уровне билд-скрипта.
По сути задачи у нас следующие:
- Использовать для сборок разные ресурсы
- Настроить свой applicationId для каждой сборки
Попробуем всё это сделать.
BuildType и ProductFlavor
Все видели buildTypes
в грэдловском билд-скрипте. Более-менее понятно, зачем нужны сборки debug и release: в дебаге отключаем статистику и краш-репорты, зато включаем логи, в релизе наоборот.
Понятие flavor кажется очень похожим. Я формулирую отличие так: BuildType
— это тип сборки, и он используется только при разработке, а ProductFlavor
— вариация приложения, и она уже имеет значение для пользователя. Так что debug/release — это BuildType, а free/premium — ProductFlavor. А ещё вариации можно объединять и получать что-то вроде app-samsung-free или app-amazon-premium (об этом будет в следующей части), а типы билдов несочетаемы.
Полезно взглянуть на объектные модели этих сущностей. Не то чтобы это прояснит разницу между ними, но знать, как они конфигурируются, нелишне.
Вариации и структура проекта
Вариации можно определить в билд-скрипте в разделе productFlavors
. Для нашего случая всё начинается с этого:
app/build.gradle
android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { applicationId "com.demos.productflavors" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }productFlavors { free { } premium { } }}
Определить ресурсы и логику, специфичные для вариации, довольно просто. Просто создаём в папке src
подпапки free
и premium
, реализуем ту же структуру, что и в main
— и готово. Например, чтобы сделать у free и premium разные иконки, надо всего лишь рассовать нужные картинки по mipmap-папочкам:
Для отключения части функциональности во free-версии тоже можно обойтись ресурсами: создать values.xml
, завести там флаг is_premium
и проверять его везде, где хочется что-нибудь ограничить. А можно заняться архитектурными излишествами и наворотить кода, но об этом в следующий раз.
Application Id
Тут всё очевидно. В объектной модели у ProductFlavor
есть applicationId
, мы его указываем и получаем две независимые сборки.
productFlavors { premium { applicationId "com.demos.productflavors.premium" } free { applicationId "com.demos.productflavors" } }
Про разницу между application id и package name можно почитать в документации к Android Build Tools. Вкратце, application id используется извне (при публикации, при размещении на устройстве и т.д.), а package name — при разработке (импорт класса R
).
На этом пока всё. В следующей части рассмотрим более сложные задачи.
Спасибо что не забросила блог.
ОтветитьУдалитьЧитал еще в 2010м году. С возвращением!
ОтветитьУдалить