Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Understanding Your (Android) Builds

Understanding Your (Android) Builds

Gradle is the official build tool for Android Apps. This talk covers some basics on Gradle build scripts and shows some sample tasks you can have in your project build.

Charles Muchene

October 04, 2018
Tweet

More Decks by Charles Muchene

Other Decks in Technology

Transcript

  1. Understanding your
    builds
    twitter.com

    github.com
    @charlesmuchene

    View Slide

  2. Understanding your
    builds
    twitter.com

    github.com
    @charlesmuchene
    • Introduction

    • AS & Gradle

    • Groovy basics

    • Android Build Process

    • Sample tasks
    Agenda

    View Slide

  3. @SafeBoda | @SafeBoda_Kenya

    View Slide

  4. 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

    View Slide

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

    View Slide

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

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  13. 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

    View Slide

  14. Gradle-Wrapper

    View Slide

  15. 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

    View Slide

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

    View Slide

  17. • 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

    View Slide

  18. Android Build Process
    android.com

    View Slide

  19. 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

    View Slide

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

    View Slide

  21. 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()
    }
    }

    View Slide

  22. 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
    }

    View Slide

  23. 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
    }
    }

    View Slide

  24. 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'
    }
    }
    }
    }

    View Slide

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

    View Slide

  26. 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

    View Slide

  27. 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'])
    }
    }
    ..

    View Slide

  28. 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

    View Slide