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 • Introduction • AS

    & Gradle • Groovy basics • Android Build Process • Sample tasks Agenda
  2. 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
  3. AS & Gradle AS delegates the entire build process to

    Gradle Building Android apps ADB :assemble artifact Install using adb
  4. 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
  5. 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
  6. Groovy cntd. def builderTask(Closure configClosure) { // All good stuff

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

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

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

    using configClosure } builderTask { // Does awesome work } closures Definition: Invocation:
  10. 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
  11. 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
  12. Tasks Self-contained unit of work task <task-name>[(configs.)] { // actions

    } gradle <task-name> Executing a task: Task syntax: gradle tasks Show all tasks:
  13. • 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
  14. 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
  15. settings.gradle specifies modules to be included when building your app

    include ‘:app’ include ‘:app’, ‘:common’
  16. 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() } }
  17. 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 }
  18. 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 } }
  19. 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' } } } }
  20. 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
  21. 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']) } } ..