Gradle је систем за изградњу који аутоматизује компајлирање, тестирање и паковање Android апликација. За разлику од Apache Ant или Maven, подржава инкременталну изградњу и кеширање резултата. Више о могућностима прочитајте у званичној документацији Gradle-а. Од 2013. године алат се користи као стандардни систем за изградњу за Android пројекте у Android Studio-у.
Главно
Gradle је алат за аутоматизацију изградње отвореног кода написан у Java-и, који ради на JVM-у. Он на улазу прима изворни код, зависности и ресурсе, а на излазу даје готову апликацију — APK или AAB за Android. У основи Gradle-а лежи концепт усмјереног ацикличног графа задатака (DAG), гдје је сваки задатак атомска јединица рада, а везе међу њима одређују редослед извршења. За разлику од Make-а или Ant-а, Gradle не захтијева ручно описивање секвенце корака: довољно је прогласити зависности између задатака и систем ће сам изградити оптимални редослед. Овакав приступ чини Gradle флексибилним и скалабилним за пројекте било које величине.
Систем користи три фазе извршења: иницијализацију (одређивање учествујућих пројеката), конфигурацију (изградња графа задатака) и извршење (покретање задатака у потребном реду). Фаза конфигурације је кључна разлика Gradle-а: цијели скрипт изградње се извршава прије покретања задатака, што омогућава динамичко мијењање графа у зависности од услова. Ово даје могућност, на примјер, додавања задатака само за одређене варијанте изградње без дуплирања кода. Изградник је написан у Groovy-ју, али конфигурациони фајлови подржавају два језика: Groovy DSL и Kotlin DSL.
Android додатак за Gradle — com.android.application и com.android.library, који додају у пројекат задатке за рад са Android алатима. Када програмер покрене изградњу, Gradle секвенцијално извршава десетине задатака: компајлирање Kotlin-а и Java-е кроз javac или kotlinc, обраду ресурса кроз AAPT2, генерисање R.java, компајлирање бајткода у DEX кроз D8 или R8, потписивање и зиповање APK-а. Сваки задатак провјерава да ли су му се улазни подаци промијенили, и ако нису — користи кеширани резултат. Овај механизам се назива инкрементална изградња и убрзава поновно компајлирање за 60–80% у поређењу са потпуном преградњом.
Конфигурација Android модула се задаје у блоку android фајла build.gradle.kts. Унутар блока се дефинишу compileSdk, minSdk, targetSdk, верзија апликације, потписи и други параметри. Gradle аутоматски креира за сваки модул неколико варијанти изградње — комбинацију типа (release, debug) и укуса. На примјер, за модул са два укуса и два типа Gradle генерише четири задатка: assembleDemoDebug, assembleDemoRelease, assembleFullDebug, assembleFullRelease. Сви ови задаци се могу извршавати одвојено или покренути једном командом за све варијанте одједном.
Сваки Android пројекат садржи два нивоа конфигурације: корјенски build.gradle.kts (подешавања за све модуле) и модулски build.gradle.kts (подешавања за конкретни модул). У корјенском фајлу се проглашавају додаци без примјене, репозиторијуми и заједничке промјенљиве. У модулском фајлу додаци се примјењују на конкретни модул и подешавају се параметри изградње. Овакав приступ омогућава централизовано управљање верзијама зависности кроз каталог верзија или ext-блок.
@Suppress("UnstableApiUsage")
plugins {
id("com.android.application") version "8.2.2"
id("org.jetbrains.kotlin.android") version "1.9.22"
}
android {
namespace = "com.example.myapp"
compileSdk = 34
defaultConfig {
applicationId = "com.example.myapp"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
}
}Блок dependencies — још један критични елемент build.gradle.kts-а. У њему се набрајају библиотеке, модули и фајловске зависности које су потребне апликацији. Gradle подржава неколико конфигурација зависности: implementation (доступна само текућем модулу), api (доступна и зависним модулима), testImplementation (само за тестове), androidTestImplementation (за инструменталне тестове) и compileOnly (само у фази компајлирања). Свака конфигурација управља видљивошћу класа у графу зависности, што утиче на вријеме изградње и величину финалног артефакта.
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.activity:activity-compose:1.8.2")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
}Build variant — комбинација build type-а и product flavor-а која одређује верзију апликације са јединственим подешавањима, кодом и ресурсима. Build type (тип изградње) задаје параметре паковања: debug (са отклањањем грешака и суфиксом .debug) или release (са обфускацијом и потписом). Product flavor (продуктови укус) одређује функционалне варијанте: на примјер, demo (ограничена верзија) и full (пуна верзија са додатним могућностима). Gradle аутоматски генерише задатке за сваку комбинацију, што омогућава изградњу свих верзија једном командом.
android {
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
debug {
applicationIdSuffix = ".debug"
}
}
flavorDimensions += "version"
productFlavors {
create("demo") {
dimension = "version"
applicationIdSuffix = ".demo"
}
create("full") {
dimension = "version"
applicationIdSuffix = ".full"
}
}
}Сваком build variant-у одговара посебан source set. Gradle користи директоријуме src/demo/release, src/full/debug и друге, гдје се чувају јединствени ресурси, манифести и изворни код за конкретну варијанту. Заједнички код остаје у src/main. Овакав приступ омогућава поновно коришћење главне логике и замјену само разликујућих дијелова: стрингова, иконица, API-ендпоинта или конфигурационих фајлова. Source set може прегазити било које ресурсе из main-а: манифест, drawable, values или чак Kotlin класе. При изградњи конкретне варијанте Gradle обједињује фајлове из main-а и одговарајућег source set-а, при чему фајлови из варијанте имају приоритет.
Екосистем додатака Gradle-а покрива све фазе развоја Android апликација. Званични додаци од Google-а укључују com.android.application (за модул апликације), com.android.library (за библиотечки модул), com.android.test (за тестне модуле) и Kotlin додатке од JetBrains-а. Додаци додају у пројекат нове задатке, проширују DSL новим блоковима конфигурације и повезују додатне алате. Без додатка com.android.application пројекат не може изградити APK: овај додатак региструје све Android-специфичне задатке и повезује их у граф изградње.
Додаци трећих страна рјешавају уже задатке. Google Services (com.google.gms.google-services) интегрише Firebase и Google Play Services, аутоматски убацујући google-services.json у изградњу. Hilt (dagger.hilt.android.plugin) генерише код за убризгавање зависности у фази компајлирања. Safe Args (androidx.navigation.safeargs.kotlin) ствара типно безбједне класе за навигацију између фрагмената. Сваки додатак се повезује у корјенском build.gradle.kts кроз блок plugins и обично захтијева минималну конфигурацију. Gradle аутоматски рјешава транзитивне зависности између додатака и гарантује компатибилност верзија кроз Bom фајлове и каталог верзија.
Таск (задатак) — атомска јединица рада у Gradle-у. Сваки таск има улазне податке, излазне податке и радњу. Уграђени таскови за Android укључују assemble (изградња свих варијанти), lint (провјера кода), test (покретање unit тестова) и clean (чишћење привремених фајлова). Програмер може додавати сопствене таскове помоћу Groovy или Kotlin DSL-а. Прилагођени таскови су корисни за аутоматизацију рутинских операција: генерисање извјештаја, копирање артефаката, деплој на тестне уређаје или интеграцију са CI системима.
tasks.register("printBuildInfo") {
description = "Приказује информације о изградњи"
group = "custom"
doLast {
println("Build variant: ${project.name}")
println("Version: ${android.defaultConfig.versionName}")
}
}Сваки таск може зависити од других таскова кроз механизам dependsOn. Ако таск A зависи од таска B, Gradle гарантује да ће се B извршити прије A. Систем не захтијева ручно навођење редослиједа за сваки пар — довољно је прогласити зависности, и Gradle ће изградити усмјерени граф, оптимизован за паралелно извршење независних таскова. Уграђени таскови Android додатка су већ повезани међусобно: lint зависи од компајлирања, test зависи од assemble-а, assembleDebug зависи од compileDebugKotlin-а. Програмер може уградити своје таскове у било који чвор графа користећи dependsOn, mustRunAfter или shouldRunAfter.
Један од честих проблема — конфликт верзија зависности, када двије библиотеке захтијевају различите верзије исте транзитивне зависности. Gradle пријављује грешку конфликта, али не нуди увијек аутоматско рјешење. За дијагностику користите команду ./gradlew :app:dependencies, која приказује пуно стабло зависности. Препоручује се принудно навођење верзије конфликтне библиотеке кроз блок resolutionStrategy. Други уобичајени сценарио — спора изградња због недостатка инкременталне обраде. Провјерите да су сви додаци ажурирани, Gradle Daemon укључен (org.gradle.daemon=true) и да је у gradle.properties постављена довољна количина меморије: org.gradle.jvmargs=-Xmx4096m.
Проблеми са кеширањем настају након ажурирања зависности: Gradle може користити застарјели кеш и изградња се завршава грешком. Рјешење — покрените изградњу са заставом --refresh-dependencies или очистите кеш ручно кроз ./gradlew cleanBuildCache. Трећа по учесталости грешка — некомпатибилност верзија Android Gradle Plugin (AGP) и Gradle-а. Свака верзија AGP-а захтијева одређену минималну верзију Gradle-а. Табела компатибилности се објављује на developer.android.com. Ако верзије нису компатибилне, Gradle се завршава грешком у фази конфигурације са поруком о минималној потребној верзији. Увијек провјеравајте да верзија Gradle wrapper-а одговара захтјевима AGP-а.
Често постављана питања
Gradle је програм-аутоматизатор изградње пројеката. Он узима ваш изворни код на Kotlin или Java, повезује библиотеке са интернета, компајлира све у бајткод и пакује у APK. Ради на JVM-у и користи декларативне скриптове умјесто ручних инструкција. Програмер треба само да опише правила, а остало Gradle ради сам.
Build.gradle се пише у Groovy-ју — динамичком језику са флексибилном синтаксом и мањом строгошћу. Build.gradle.kts користи Kotlin DSL: строга типизација, аутоматско допуњавање у Android Studio-у и провјера грешака у фази компајлирања. Google препоручује Kotlin DSL за све нове пројекте. Groovy фајлове је лакше мигрирати, али Kotlin фајлови су поузданији у одржавању.
Укључите Gradle Daemon (org.gradle.daemon=true) и паралелну изградњу (org.gradle.parallel=true). Повећајте JVM меморију на 4–8 GB кроз org.gradle.jvmargs. Користите конфигурацију пројеката на захтјев (org.gradle.configureondemand=true). За Android пројекте подесите кеширање задатака и изградњу само за потребан ABI. У Android Studio-у покрените Build Analyzer да бисте пронашли уска грла.
Build variant — комбинација build type-а (на примјер, debug или release) и product flavor-а (на примјер, demo или full). Свака варијанта може имати своје име пакета, верзију, ресурсе и изворне фајлове. Gradle аутоматски креира посебан задатак изградње за сваку варијанту. Ово омогућава изградњу више верзија апликације из једног пројекта.
Зависности се додају у блок dependencies фајла build.gradle.kts. Формат записа: configuration("group:artifact:version"). На примјер, implementation("androidx.core:core-ktx:1.12.0"). За тестове користите testImplementation, за инструменталне тестове — androidTestImplementation. Верзије је згодно измјестити у посебан каталог верзија (version catalog) кроз фајл libs.versions.toml.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође