Кілька Gradle фішок для вашого Android програми



В одну з останніх розсилок Android Weakly потрапила стаття, в якій згадали цікаві особливості організації складання проекту. Після її прочитання мені захотілося поділитися дечим з того, що я використовую для налаштування збірки Android проекту.

Позбавляємося від дублювання коду в ваших build.gradle файлах
Здавалося б проста ідея, однак такий підхід використовується досить рідко.

Припустимо, у вас є кілька модулів у додатку, в кожному з яких необхідно прописати buildToolsVersion. Часто цю задачу вирішують шляхом винесення конкретної версії в ext-змінну.
Крім цього, можна оптимізувати код, задавши значення тільки в одному місці.

Нагадаю про можливості застосування коду з іншого gradle файлу у вашому build.gradle:

apply plugin: 'com.android.application'
apply from: "$buildSystemDir/application.gradle"

А у файлі application.gradle вже можна вказати потрібні версії:

чоловічий {
compileSdkVersion 24
buildToolsVersion "24.0.1"

defaultConfig {
minSdkVersion 15
targetSdkVersion 24
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}


compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}

Сюди ви можете винести будь-які налаштування всього проекту. Потім, в кожному конкретному модулі ви можете перевизначити значення (при необхідності).

В окремий gradle файл можна винести не тільки конфігурації android — extension, але і тестові залежності, налаштування jacoco, findbugs, pmd і т. д. і т. п.

Додаємо властивості проект
Можливо ви вже помітили змінну$buildSystemDir". Вона задана в build.gradle файлі кореневого проекту:

allprojects {
it.extensions.add("buildSystemDir", "$rootProject.projectDir/buildSystem/")
}

Після цього в кожному модулі цю властивість можна використовувати без будь-яких префіксів. Що, знову ж, трохи скорочує код ;)

Підпис apk
Тема безпечного зберігання ключів і паролів від сертифіката — дуже цікава, і я буду дуже радий, якщо хтось підкаже хороше рішення (з ci, безпечне), а поки я наведу свій варіант.

Інформація про кожному сертифікаті зберігається в *.properties файлі. Він може бути присутнім на машині складання проекту так і відсутнім.

sign.gradle:
Properties signProp = new Properties()
try {
signProp.load(rootProject.file('signForTest.properties').newDataInputStream())

project.ext {
forTest = new Object() {
def storeFile = signProp.get("forTest.storeFile")
def storePassword = signProp.get("forTest.storePassword")
def keyAlias = signProp.get("forTest.keyAlias")
def keyPassword = signProp.get("forTest.keyPassword")
}
}
} catch (IOException e) {
project.ext {
forTest = new Object() {
def storeFile = "/"
def storePassword = ""
def keyAlias = ""
def keyPassword = ""
}
}
}

android {
signingConfigs {
forTest {
storeFile file(project.ext.forTest.storeFile)
storePassword project.ext.forTest.storePassword
keyAlias project.ext.forTest.keyAlias
keyPassword project.ext.forTest.keyPassword
}
}
}

От і все. Залишилося застосувати цей файл у build.gradle нашого додатка і використовувати сконфігурований signingConfig в нашому buildType.

buildSrc
Що ж робити, коли в системі складання потрібен повноцінний код, а свій плагін писати немає часу? Для цього можна використовувати директорію buildSrc.

В кореневому каталозі вашого проекту (там де лежить gradlew) створюємо новий модуль buildSrc. Цей модуль повинен бути звичайним java проектом (або groovy або чим-небудь ще), з наступним build.gradle файлом:

apply plugin: "groovy"

repositories {
mavenCentral()
}

dependencies {
compile localGroovy()
compile gradleApi()
}

// START SNIPPET addToRootProject
rootProject.dependencies {
runtime project(path)
}
// END SNIPPET addToRootProject

Тепер в цьому проекті можна створити який-небудь клас Awesome.groovy, а у build.gradle Android модуля цей клас імпортувати та використовувати.

При запуску складання вашого проекту в першу чергу буде виконаний build модуля buildSrc. Після чого відбудеться конфігурація інших модулів.

Не можу сказати, що рекомендую використовувати дане рішення, оскільки це трохи збільшує час складання проекту з нуля. Але в крайньому випадку може знадобитися.

Flavor dimensions
Ця можливість для конфігурування проекту добре описана в доках (// tools.android.com/tech-docs/new-build-system/user-guide#TOC-Multi-flavor-variants
). Але про неї не всі знають, або не розуміють, в яких випадках її можна використовувати, тому я вирішив про це розповісти.

Припустимо, вам необхідно створити платне і безкоштовне додаток. При цьому ваш додаток випускається для телевізорів, планшетів і телефонів. Більш того, ваш додаток публікується в різних маркетах.

Додамо в свій build.gradle наступний код:

чоловічий {
flavorDimensions "device", "paid", "market"

productFlavors {
tv {
dimension 'device'
}
tablet {
dimension 'device'
}
phone {
dimension 'device'
}

free {
dimension 'paid'
}
premium {
dimension 'paid'
}

google {
dimension 'market'
}

amazon {
dimension 'market'
}
}
}

Оголосивши 7 flavor-ів в трьох різних групах ви отримали цілих 12 різних варіантів програми. Додамо сюди ще buildTypes, і ми отримаємо величезну кількість apk-шек.

phoneFreeGoogleDebug
phoneFreeGoogleRelease
phoneFreeAmazonDebug
phoneFreeAmazonDebug
phonePremiumGoogleDebug
… і т. д.

Для кожного оголошеного вами flavor створюються свої sourceSet. Наприклад, якщо ви вибрали флавор phoneFreeAmazonDebug будуть використані наступні sourceSets:

src/phoneFreeAmazon
src/phoneFree
src/phoneAmazon
src/freeAmazon
src/phone
src/free
src/amazon

Таким чином, відкриваються широкі можливості для кастомізації збірок.

Вказуємо minSdkVersion для buildType
Для прискорення складання програми на етапі розробки часто рекомендують створити окремий flavor «develop» і вказати для нього minSdkVersion = 21. Однак, це не дуже зручно, і часто хочеться вказати цей параметр buildType debug. Спочатку, плагін збірки не дозволяє цього зробити, однак, при необхідності, цю проблему можна вирішити наступним хайком.
Для потрібного buildType необхідно додати ext змінну:

...
buildTypes {
...
debug {
... 
ext.minSdkVersion = 21
}
}

Нижче необхідно додати наступний код:

preBuild.doFirst {
android.applicationVariants.all {
if (it.buildType.hasProperty("minSdkVersion")) {
int i = it.buildType.ext.minSdkVersion;
it.mergedFlavor.setMinSdkVersion(new com.android.builder.core.DefaultApiVersion(i))
}
}
}

Тепер для всіх ваших flavor в debug збірці minSdkVersion буде 21. Однак, тут є жорстка зав'язка на нутрощі плагіна, тому при оновленні версії плагіна щось може зламатися. Тому, не можу рекомендувати використовувати цей хак — вибір за вами.

Замість висновків хочу зазначити, що Gradle — дуже потужний інструмент для складання проекту. Якщо ви приділяєте багато уваги якості коду вашого додатки, то не забувайте приводити в порядок та код build.gradle файлах.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.