Рассмотрим распространённую задачу: есть приложение, у которого есть две версии — ограниченная и полная. Они выпускаются с разными 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м году. С возвращением!
ОтветитьУдалить