Slide 1

Slide 1 text

Understanding your builds twitter.com github.com @charlesmuchene

Slide 2

Slide 2 text

Understanding your builds twitter.com github.com @charlesmuchene • Introduction • AS & Gradle • Groovy basics • Android Build Process • Sample tasks Agenda

Slide 3

Slide 3 text

@SafeBoda | @SafeBoda_Kenya

Slide 4

Slide 4 text

Gradle • Highly customisable - custom build configs, plugins etc • Fast - employs caching, incremental, *parallel builds etc • Powerful - supports popular languages and technologies open-source build and automation tool

Slide 5

Slide 5 text

AS & Gradle AS delegates the entire build process to Gradle Building Android apps ADB :assemble artifact Install using adb

Slide 6

Slide 6 text

The basics Gradle scripts are written using *Groovy (and now Kotlin)

Slide 7

Slide 7 text

Groovy def age = 23 String name = "SenseiDev" def someFunction(a, b) { // Does awesome stuff } class Session { String title = "Understanding your builds" def printTitle() { println "Session title: $title" } } variables, functions, classes

Slide 8

Slide 8 text

Groovy cntd. def event = “Droidcon" def country = "KE" def posterPrinter = { println "Attending ${event}${country}" } posterPrinter() def adder = {a, b -> a + b} def result = adder 7, 3 println result closures

Slide 9

Slide 9 text

Groovy cntd. def builderTask(Closure configClosure) { // All good stuff using configClosure } def closureImpl = { // Does awesome work } builderTask(closureImpl) closures Definition: Invocation:

Slide 10

Slide 10 text

Groovy cntd. def builderTask(Closure configClosure) { // All good stuff using configClosure } builderTask({ // Does awesome work }) closures Definition: Invocation:

Slide 11

Slide 11 text

Groovy cntd. def builderTask(Closure configClosure) { // All good stuff using configClosure } builderTask() { // Does awesome work } closures Definition: Invocation:

Slide 12

Slide 12 text

Groovy cntd. def builderTask(Closure configClosure) { // All good stuff using configClosure } builderTask { // Does awesome work } closures Definition: Invocation:

Slide 13

Slide 13 text

Groovy cntd. class AppBuilder { String platform = "Unknown" def build() { println "Building for $platform..." } } def appBuilder = new AppBuilder() def buildApp = { platform = "Android" build() } buildApp.delegate = appBuilder buildApp() delegates

Slide 14

Slide 14 text

Gradle-Wrapper

Slide 15

Slide 15 text

Gradle-Wrapper Micro-library for downloading distribution List dist. url, version and other options Gradle executable for *nix systems Gradle executable for Windows systems ~150Kb

Slide 16

Slide 16 text

Tasks Self-contained unit of work task [(configs.)] { // actions } gradle Executing a task: Task syntax: gradle tasks Show all tasks:

Slide 17

Slide 17 text

• Initialization Phase Configure environment (init.gradle, gradle.properties) Find projects and build scripts (settings.gradle) • Configuration Phase Evaluate all build scripts Build task execution graph • Execution Phase Execute tasks Gradle Build lifecycle

Slide 18

Slide 18 text

Android Build Process android.com

Slide 19

Slide 19 text

App module structure • settings.gradle - what modules should be included • build.gradle (project-level) - configurations for all modules in the project e.g. • build.gradle (module-level) - configures build settings for the module • *gradle.properties - project-wide Gradle settings e.g. caching, daemon max heap size etc • **local.properties - local environment properties for the build system e.g. local sdk, ndk paths

Slide 20

Slide 20 text

settings.gradle specifies modules to be included when building your app include ‘:app’ include ‘:app’, ‘:common’

Slide 21

Slide 21 text

build.gradle (project-level) configurations for all modules in project buildscript { repositories { google() jcenter() } dependencies { classpath ‘com.android.tools.build:gradle:3.2.0’ classpath ‘org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.71’ } } allprojects { repositories { google() jcenter() } }

Slide 22

Slide 22 text

build.gradle (module-level) configurations for a module apply plugin: ‘com.android.application’ apply plugin: ‘kotlin-android’ apply plugin: ‘kotlin-android-extensions’ apply plugin: ‘kotlin-kapt’ android { ... // additional configurations } dependencies { ... // dependencies list }

Slide 23

Slide 23 text

build.gradle (module-level) configurations for a module (contd.) android { compileSdkVersion 28 defaultConfig { versionCode 87 minSdkVersion 21 targetSdkVersion 28 versionName "3.2.10-alpha.1" applicationId “com.charlesmuchene.app" buildConfigField "String", “INSTABUG_TOKEN", “ab12cd34" ... // additional configurations } }

Slide 24

Slide 24 text

build.gradle (module-level) configurations for a module (contd.) android { defaultConfig { ... // other configurations buildTypes { beta { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile(‘proguard-android.txt'), 'proguard-rules.pro' } release { minifyEnabled true shrinkResources true buildConfigField "String", "INSTABUG_TOKEN", ‘"zz98yy76"' proguardFiles getDefaultProguardFile(‘proguard-android.txt'), 'proguard-rules.pro' } } } }

Slide 25

Slide 25 text

Sample task task clean(type: Delete) { delete rootProject.buildDir } remove build dir.

Slide 26

Slide 26 text

Sample task task exportArtifacts(type: Copy) { description "Copy artifacts for distribution to project root” group "Installer Automator” dependsOn assemble, assembleAndroidTest from("$buildDir/outputs/apk/debug") { exclude "*.json" rename "(.*)\\.apk", "install-checker.apk" } from("$buildDir/outputs/apk/androidTest/debug") { exclude "*.json" rename "(.*)\\.apk", "install-automator.apk" } into("$rootDir/artifacts") } export artifacts to a custom directory

Slide 27

Slide 27 text

Sample configuration read signing configs from excluded properties file def keystorePropertiesFile = rootProject.file("keystore.properties") if (keystorePropertiesFile.exists()) { def key = new Properties() key.load(new FileInputStream(keystorePropertiesFile)) android { signingConfigs { debug { storeFile rootProject.file('debug.keystore') } config { keyAlias key['alias'] keyPassword key['key'] storePassword key['store'] storeFile file(key['file']) } } ..

Slide 28

Slide 28 text

References • http://groovy-lang.org • https://docs.gradle.org/current/dsl/ • https://developer.android.com/studio/build/ • https://google.github.io/android-gradle-dsl/current/ Happy building