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

Playing nice with Gradle - droidcon KE

Playing nice with Gradle - droidcon KE

Presentation given at droidcon KE, Nairobi, 2019

Abstract:
Gradle is the most popular build system in use today for building Android projects. It is an amazing tool that has improved how we build projects especially when we compare to the previous build systems used for Android development.

As your project starts to scale, so does the Gradle setup start to get complicated - from build performance, to configuring plugins, to managing dependencies, to managing multiple modules. Gradle by default makes use of Groovy language, which often does not provide the full features of static typing - hence making it more difficult to customize.

If like me, you’re in a love-hate relationship with Gradle, then, this talk is for you.

In this talk, we will go through top tips to make Gradle work for us as Android developers.

We will talk about different quick wins to make maintaining our Gradle configuration easy by:
avoiding repetitive code as your project modules continue to grow, and
writing your build configuration partly or fully in Kotlin, hence taking advantage of the Kotlin DSL feature.
You will leave this talk with a lot of ideas of how to improve the Gradle setup of your project.

Most of these ideas will be something you can immediately implement while some may require a little more effort. Ultimately we will be able to make Gradle work for you to achieve the best results.

Resource links in the slides:
https://handstandsam.com/2019/03/12/sharing-gradle-configuration-in-multi-module-android-projects/
https://segunfamisa.com/posts/android-gradle-extra-properties
https://gradle.com/blog/getting-started-with-gradle-kotlin-dsl/
https://github.com/gradle/kotlin-dsl
https://blog.codinghorror.com/rule-of-three/

Segun Famisa

August 09, 2019
Tweet

More Decks by Segun Famisa

Other Decks in Programming

Transcript

  1. Playing nice with Gradle the elephant in the room Segun

    Famisa, Android GDE droidcon KE August, 2019
  2. Outline • Introduction • Scenarios & improvements #0, #1, #2

    • Taking it a step further with Kotlin DSL • buildSrc • Migrating build scripts to Kotlin DSL from Groovy DSL • Kotlin DSL improvements • Resources
  3. #0

  4. // <app> build.gradle apply plugin: 'com.android.application' ... dependencies { ...

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "io.reactivex.rxjava2:rxjava:2.2.5" } #0
  5. // <networking-lib> build.gradle apply plugin: 'kotlin' ... dependencies { ...

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "io.reactivex.rxjava2:rxjava:2.2.5" } // <app> build.gradle apply plugin: 'com.android.application' ... dependencies { ... implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "io.reactivex.rxjava2:rxjava:2.2.5" } #0
  6. // <app> build.gradle apply plugin: 'com.android.application' ... dependencies { ...

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "io.reactivex.rxjava2:rxjava:2.2.5" } // <networking-lib> build.gradle apply plugin: 'kotlin' ... dependencies { ... implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "io.reactivex.rxjava2:rxjava:2.2.5" } #0
  7. #0 // <app> build.gradle apply plugin: 'com.android.application' ... dependencies {

    ... implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "io.reactivex.rxjava2:rxjava:2.2.5" } // <networking-lib> build.gradle apply plugin: 'kotlin' ... dependencies { ... implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "io.reactivex.rxjava2:rxjava:2.2.5" } Managing dependencies versions becomes tedious
  8. // dependencies.gradle ext { ... libraries = [ rxJavaVersion :

    '2.2.5' rxAndroidVersion : '2.1.0' kotlinVersion : '1.3.31' ] } 1. Externalize dependencies
  9. 1. Externalize dependencies 2. Apply dependencies.gradle to root project //

    root build.gradle buildScript {...} allprojects {...} apply from: 'relative/path/to/dependencies.gradle'
  10. 1. Externalize dependencies 2. Apply dependencies.gradle to root project 3.

    Reference the dependencies in the build.gradle files // <app> build.gradle dependencies { ... def libs = rootProject.ext.libraries implementation "org.jetbrains.kotlin:...:$libs.kotlinVersion" implementation "io.reactivex.rxjava2:rxjava:$libs.rxJavaVersion" }
  11. 1. Externalize dependencies 2. Apply dependencies.gradle to root project 3.

    Reference the dependencies in the build.gradle files // <app> build.gradle dependencies { implementation "org.jetbrains.kotlin:...:$libs.kotlinVersion" implementation "io.reactivex.rxjava2:rxjava:$libs.rxJavaVersion" } // <networking-lib> build.gradle dependencies { ... def libs = rootProject.ext.libraries implementation "org.jetbrains.kotlin:...:$libs.kotlinVersion" implementation "io.reactivex.rxjava2:...:$libs.rxJavaVersion" }
  12. 1. Externalize dependencies 2. Apply dependencies.gradle to root project 3.

    Reference the dependencies in the build.gradle files // <app> build.gradle dependencies { implementation "org.jetbrains.kotlin:...:$libs.kotlinVersion" implementation "io.reactivex.rxjava2:rxjava:$libs.rxJavaVersion" } // <networking-lib> build.gradle dependencies { ... def libs = rootProject.ext.libraries implementation "org.jetbrains.kotlin:...:$libs.kotlinVersion" implementation "io.reactivex.rxjava2:...:$libs.rxJavaVersion" }
  13. • Managing/updating versions of dependencies is now easier - just

    need to change in one place • Still has the problem of duplication of dependencies
  14. #1

  15. #1 • Fairly complex projects • Multiple modules • You

    will find a lot of repetitions in the dependencies
  16. #1 // <login> build.gradle dependencies { implementation fileTree(dir: 'libs', include:

    ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies }
  17. #1 // <login> build.gradle dependencies { implementation fileTree(dir: 'libs', include:

    ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <profile> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies }
  18. #1 // <login> build.gradle dependencies { implementation fileTree(dir: 'libs', include:

    ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <profile> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <search> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies }
  19. #1 // <login> build.gradle dependencies { implementation fileTree(dir: 'libs', include:

    ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <profile> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <search> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <core> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies }
  20. #1 // <login> build.gradle dependencies { implementation fileTree(dir: 'libs', include:

    ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <profile> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <search> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } // <core> build.gradle dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" testImplementation "junit:junit:$libs.jUnitVersion" ... // other dependencies } Problem: Repeated declarations of dependencies in so many modules
  21. 1. Extract common dependencies // shared-dependencies.gradle - contains all shared

    dependncies dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion" ... testImplementation 'junit:junit:4.12' }
  22. 1. Extract common dependencies 2. Apply common dependencies to respective

    modules // <login> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies }
  23. 1. Extract common dependencies 2. Apply common dependencies to respective

    modules // <login> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies } // <profile> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies }
  24. 1. Extract common dependencies 2. Apply common dependencies to respective

    modules // <login> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies } // <profile> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies } // <search> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies }
  25. 1. Extract common dependencies 2. Apply common dependencies to respective

    modules // <login> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies } // <profile> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies } // <search> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies } // <core> build.gradle apply from: “relative/path/to/shared-dependencies.gradle" ... dependencies { ... // other dependencies }
  26. #2

  27. #2 • Fairly complex projects • Multiple modules • You

    will find a lot of repetitions in the configurations of the modules
  28. #2

  29. #2 // <login> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion

    defaultConfig { minSdkVersion sdk.minSdkVersion targetSdkVersion sdk.targetSdkVersion versionCode 198828 versionName "1.5.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' ... } buildTypes {...} }
  30. #2 // <login> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion

    defaultConfig {...} buildTypes { debug { minifyEnabled ... proguardFiles ... } release { minifyEnabled ... proguardFiles ... } } }
  31. #2 // <login> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion

    defaultConfig {...} buildTypes {...} } // <profile> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion defaultConfig {...} buildTypes {...} }
  32. #2 // <login> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion

    defaultConfig {...} buildTypes {...} } // <profile> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion defaultConfig {...} buildTypes {...} } // <search> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion defaultConfig {...} buildTypes {...} }
  33. #2 // <login> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion

    defaultConfig {...} buildTypes {...} } // <profile> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion defaultConfig {...} buildTypes {...} } // <search> build.gradle android { compileSdkVersion sdk.compileSdkVersion buildToolsVersion sdk.buildToolsVersion defaultConfig {...} buildTypes {...} } Problem: Repeated configuration in so many modules
  34. 1. Extract common configuration into separate file https://handstandsam.com/2019/03/12/sharing-gradle-configuration-in-multi-module-android-projects/ // common-android-config.gradle

    apply plugin: 'kotlin-android' android { compileSdkVersion sdk.compileSdkVersion defaultConfig { minSdkVersion sdk.minSdkVersion targetSdkVersion sdk.targetSdkVersion versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } } Further reading:
  35. 1. Extract common configuration into separate file https://handstandsam.com/2019/03/12/sharing-gradle-configuration-in-multi-module-android-projects/ Further reading:

    2. Apply config to android modules // <login> build.gradle apply from: "$rootProject.projectDir/common-android-config.gradle" ...
  36. • Eliminates repeated configuration of common build logic • Same

    applies to other common configuration you may have across multiple modules. https://handstandsam.com/2019/03/12/sharing-gradle-configuration-in-multi-module-android-projects/ Further reading:
  37. Why Kotlin DSL? • Kotlin is now really popular •

    Same language for code & build logic
  38. Why Kotlin DSL? • Kotlin is now really popular •

    Same language for code & build logic • Better IDE support for build scripts in Kotlin. • Jump to declaration, syntax highlighting, etc
  39. Tips for migrating to Kotlin DSL 1. <file.gradle> becomes <file.gradle.kts>

    2. Single quotes become double quotes 3. Property assignments should have assignment operator ‘=‘ 4. Function calls should have parenthes
  40. buildSrc • Gradle allows us create a module to add

    complex build related logic - like plugins, custom tasks, etc.
  41. buildSrc • Gradle allows us create a module to add

    complex build related logic - like plugins, custom tasks, etc. • It’s a regular module with it’s own: • build.gradle.kts • src/main/java or src/main/kotlin
  42. dependencies.gradle -> dependencies.kt // Dependencies.kt object SdkVersions { const val

    compileSdkVersion = 28 const val minSdkVersion = 21 const val targetSdkVersion = 28 } object Deps { const val kotlinStdLib = “org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.41" const val gson = “com.google.code.gson:gson:2.8.5" ... object Rx { const val rxJava2 = "io.reactivex.rxjava2:rxjava:2.2.10" const val rxAndroid = "io.reactivex.rxjava2:rxandroid:2.1.1" } ... }
  43. dependencies.gradle -> dependencies.kt // Dependencies.kt object SdkVersions { const val

    compileSdkVersion = 28 const val minSdkVersion = 21 const val targetSdkVersion = 28 } object Deps { const val kotlinStdLib = “org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.41" const val gson = “com.google.code.gson:gson:2.8.5" ... object Rx { const val rxJava2 = "io.reactivex.rxjava2:rxjava:2.2.10" const val rxAndroid = "io.reactivex.rxjava2:rxandroid:2.1.1" } ... }
  44. dependencies.gradle -> dependencies.kt // Dependencies.kt object Deps { const val

    kotlinStdLib = “org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.41" const val gson = “com.google.code.gson:gson:2.8.5" } // Usage in build.gradle dependencies { implementation Deps.kotlinStdLib implementation Deps.gson ... }
  45. dependencies.gradle -> dependencies.kt // Dependencies.kt object Deps { const val

    kotlinStdLib = “org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.41" const val gson = “com.google.code.gson:gson:2.8.5" } // Usage in build.gradle dependencies { implementation Deps.kotlinStdLib implementation Deps.gson ... } Syntax highlighting ✅ “Jump to declaration” ✅
  46. // settings.gradle include ':app', ':data', ':domain' // settings.gradle.kts include(":app", ":data",

    ":domain") ’:app’ becomes “:app” include becomes include()
  47. // app-level build.gradle apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android

    { compileSdkVersion 28 defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true proguardFiles ... } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "androidx.appcompat:appcompat:1.0.2" }
  48. // app-level build.gradle.kts apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android

    { compileSdkVersion(28) defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion(21) targetSdkVersion(28) versionCode = 1 versionName = "1.0" } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro') } } } dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31") implementation("androidx.appcompat:appcompat:1.0.2") }
  49. What changed? apply plugin: 'com.android.application' apply plugin: 'kotlin-android' android {

    compileSdkVersion 28 defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true proguardFiles ... } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "androidx.appcompat:appcompat:1.0.2" }
  50. What changed? apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android {

    compileSdkVersion 28 defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true proguardFiles ... } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "androidx.appcompat:appcompat:1.0.2" }
  51. What changed? apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android {

    compileSdkVersion 28 defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true proguardFiles ... } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "androidx.appcompat:appcompat:1.0.2" }
  52. What changed? apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android {

    compileSdkVersion(28) defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion(21) targetSdkVersion(28) versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true proguardFiles ... } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "androidx.appcompat:appcompat:1.0.2" }
  53. What changed? apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android {

    compileSdkVersion(28) defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion(21) targetSdkVersion(28) versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled true proguardFiles ... } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "androidx.appcompat:appcompat:1.0.2" }
  54. What changed? apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android {

    compileSdkVersion(28) defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion(21) targetSdkVersion(28) versionCode 1 versionName "1.0" } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile(‘...’), 'proguard-rules.pro') } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "androidx.appcompat:appcompat:1.0.2" }
  55. What changed? apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android {

    compileSdkVersion(28) defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion(21) targetSdkVersion(28) versionCode 1 versionName "1.0" } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile(‘...’), 'proguard-rules.pro') } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31" implementation "androidx.appcompat:appcompat:1.0.2" }
  56. What changed? apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android {

    compileSdkVersion(28) defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion(21) targetSdkVersion(28) versionCode 1 versionName "1.0" } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile(‘...’), 'proguard-rules.pro') } } } dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31") implementation("androidx.appcompat:appcompat:1.0.2") }
  57. // app-level build.gradle.kts apply(plugin = "com.android.application") apply(plugin = "kotlin-android") android

    { compileSdkVersion(28) defaultConfig { applicationId "com.segunfamisa.kotlindsl" minSdkVersion(21) targetSdkVersion(28) versionCode = 1 versionName = "1.0" } buildTypes { getByName("release") { isMinifyEnabled = true proguardFiles(getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro') } } } dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.31") implementation("androidx.appcompat:appcompat:1.0.2") }
  58. // top-level build.gradle buildscript { ext.kotlin_version = '1.3.31' repositories {

    google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() jcenter() } }
  59. // top-level build.gradle.kts buildscript { extra.apply { set("kotlin_version", "1.3.31") }

    repositories { google() jcenter() } dependencies { classpath("com.android.tools.build:gradle:3.4.1") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${extras.get("kotlin_version")}) } } allprojects { repositories { google() jcenter() } }
  60. // top-level build.gradle buildscript { ext.kotlin_version = '1.3.31' repositories {

    google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() jcenter() } } What changed?
  61. What changed? // top-level build.gradle.kts buildscript { extra.apply { set("kotlin_version",

    "1.3.31") } repositories { google() jcenter() } dependencies { classpath("com.android.tools.build:gradle:3.4.1") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${extras.get("kotlin_version")}) } } allprojects { repositories { google() jcenter() } }
  62. // top-level build.gradle buildscript { extra.apply { set("kotlin_version", "1.3.31") }

    repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.4.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() jcenter() } } What changed?
  63. // top-level build.gradle.kts buildscript { extra.apply { set("kotlin_version", "1.3.31") }

    repositories { google() jcenter() } dependencies { classpath("com.android.tools.build:gradle:3.4.1") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${extras.get("kotlin_version")}) } } allprojects { repositories { google() jcenter() } } What changed?
  64. // top-level build.gradle.kts buildscript { extra.apply { set("kotlin_version", "1.3.31") }

    repositories { google() jcenter() } dependencies { classpath("com.android.tools.build:gradle:3.4.1") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${extras.get("kotlin_version")}) } } allprojects { repositories { google() jcenter() } }
  65. Current pain points with Kotlin DSL • IDE support is

    not yet at • Additional configuration time in your build process
  66. Final words • Keep it DRY (Don’t Repeat Yourself) -

    rule of three applies here • Modular code rocks
  67. Final words • Keep it DRY (Don’t Repeat Yourself) -

    rule of three applies here • Modular code rocks • Take advantage of IDE support with Kotlin DSL