Slide 1

Slide 1 text

Pragmatic Gradle for your Multi-Module Projects @CliveLeeHere

Slide 2

Slide 2 text

https://www.oviahealth.com/careers

Slide 3

Slide 3 text

https://www.oviahealth.com/careers

Slide 4

Slide 4 text

Terminology

Slide 5

Slide 5 text

{ Project

Slide 6

Slide 6 text

{ Project Root Project

Slide 7

Slide 7 text

{ Project

Slide 8

Slide 8 text

Project Modules

Slide 9

Slide 9 text

Project Modules Subproject

Slide 10

Slide 10 text

Project Modules

Slide 11

Slide 11 text

Project Modules App

Slide 12

Slide 12 text

Project Modules App Libraries

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

“Pragmatic”

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

“Multi-Module”

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

App 1 Library Feature B Feature A App 2

Slide 26

Slide 26 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Tips https://github.com/cliveleehere/multimodulegradle

Slide 30

Slide 30 text

But First…

Slide 31

Slide 31 text

But First… ! Update Gradle (4.6)

Slide 32

Slide 32 text

But First… ! Update Gradle (4.6) ! Update Android Gradle Plugin (3.0.1)

Slide 33

Slide 33 text

But First… ! Update Gradle (4.6) ! Update Android Gradle Plugin (3.0.1) ! android-cache-fix-gradle-plugin

Slide 34

Slide 34 text

But First… ! Update Gradle (4.6) ! Update Android Gradle Plugin (3.0.1) ! android-cache-fix-gradle-plugin ! Gradle Properties

Slide 35

Slide 35 text

But First… ! Update Gradle (4.6) ! Update Android Gradle Plugin (3.0.1) ! android-cache-fix-gradle-plugin ! Gradle Properties AWESOME!

Slide 36

Slide 36 text

Update Gradle ./gradle-wrapper.properties
 distributionUrl=...-4.6-all.zip

Slide 37

Slide 37 text

Update Gradle ./gradle-wrapper.properties
 distributionUrl=...-4.6-all.zip or File > Project Structure > Project

Slide 38

Slide 38 text

Android Gradle Plugin ./build.gradle classpath
 'com.android.tools.build:gradle:3.0.1' or File > Project Structure > Project

Slide 39

Slide 39 text

Android Gradle Plugin ./build.gradle classpath
 'com.android.tools.build:gradle:3.0.1' or File > Project Structure > Project

Slide 40

Slide 40 text

android-cache-fix-gradle-plugin ./build.gradle plugins { id "org.gradle.android.cache-fix" version "0.3.6" }

Slide 41

Slide 41 text

Gradle.Properties

Slide 42

Slide 42 text

Gradle.Properties org.gradle.parallel=true

Slide 43

Slide 43 text

Gradle.Properties org.gradle.parallel=true org.gradle.caching=true

Slide 44

Slide 44 text

Gradle.Properties org.gradle.parallel=true org.gradle.caching=true org.gradle.configureondemand=true

Slide 45

Slide 45 text

Gradle.Properties org.gradle.parallel=true org.gradle.caching=true org.gradle.configureondemand=true

Slide 46

Slide 46 text

Parallel Execution

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

Dependency Management

Slide 49

Slide 49 text

Terminology: Dependency

Slide 50

Slide 50 text

Terminology: Dependency ‘com.google.dagger:dagger:2.15’ implementation

Slide 51

Slide 51 text

Terminology: Dependency ‘com.google.dagger:dagger:2.15’ coordinates

Slide 52

Slide 52 text

Terminology: Dependency ‘com.google.dagger:dagger:2.15’ group coordinates

Slide 53

Slide 53 text

Terminology: Dependency ‘com.google.dagger:dagger:2.15’ group name coordinates

Slide 54

Slide 54 text

Terminology: Dependency ‘com.google.dagger:dagger:2.15’ group name coordinates version

Slide 55

Slide 55 text

The Problem

Slide 56

Slide 56 text

The Problem ./app/build.gradle implementation ‘com.google.dagger:dagger:2.15’

Slide 57

Slide 57 text

The Problem ./app/build.gradle implementation ‘com.google.dagger:dagger:2.15’ ./lib/build.gradle implementation¡ ‘com.google.dagger:dagger:2.15’

Slide 58

Slide 58 text

The Problem ./app/build.gradle implementation ‘com.google.dagger:dagger:2.15’ ./lib/build.gradle implementation¡ ‘com.google.dagger:dagger:2.15’ implementation ‘com.google.dagger:dagger-android:2.15’

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

Dependency Management, part 1

Slide 61

Slide 61 text

Dependency Management, part 1 ./build.gradle ext { DAGGER=‘2.15’ }

Slide 62

Slide 62 text

Dependency Management, part 1 ./build.gradle ext { DAGGER=‘2.15’ } ./app/build.gradle implementation “com.google.dagger:dagger:$DAGGER”

Slide 63

Slide 63 text

Dependency Management, part 1 ./app/build.gradle implementation “com.google.dagger:dagger:$DAGGER”

Slide 64

Slide 64 text

Dependency Management, part 1 ./app/build.gradle implementation “...:$rootProject.ext.daggerVersion”

Slide 65

Slide 65 text

Dependency Management, part 1 ./app/build.gradle implementation “...:$DAGGER_VERSION”

Slide 66

Slide 66 text

Dependency Management, part 2

Slide 67

Slide 67 text

Dependency Management, part 2 ./build.gradle ext { DAGGER_VERSION=‘2.15’ dagger=“com.google.dagger:dagger: $DAGGER_VERSION” } ./app/build.gradle implementation rootProject.ext.dagger

Slide 68

Slide 68 text

Dependency Management, part 2 ./build.gradle ext { DAGGER_VERSION=‘2.15’ dagger=“com.google.dagger:dagger:$DAGGER_VERSION” } ./app/build.gradle implementation rootProject.ext.dagger

Slide 69

Slide 69 text

Dependency Management, part 2 rootProject.ext.dagger

Slide 70

Slide 70 text

Dependency Management, part 2 rootProject.dagger

Slide 71

Slide 71 text

Dependency Management, part 2 dagger

Slide 72

Slide 72 text

Dependency Management, part 2 daggerLibrary

Slide 73

Slide 73 text

Dependency Management, part 3

Slide 74

Slide 74 text

Dependency Management, part 3 ./build.gradle ./app/build.gradle ./versions.gradle

Slide 75

Slide 75 text

Dependency Management, part 3 ./versions.gradle ext.deps = [:]

Slide 76

Slide 76 text

Dependency Management, part 3 ./versions.gradle ext.deps = [:] def versions = [:] versions.dagger = "2.15"

Slide 77

Slide 77 text

Dependency Management, part 3 ./versions.gradle ext.deps = [:] def versions = [:] versions.dagger = "2.15" def deps = [:] def dagger = [:] dagger.runtime = "com.google.dagger:dagger$versions.dagger"

Slide 78

Slide 78 text

Dependency Management, part 3 ./versions.gradle ext.deps = [:] def versions = [:] versions.dagger = "2.15" def deps = [:] def dagger = [:] dagger.runtime = "com.google.dagger:dagger$versions.dagger" deps.dagger = dagger ext.deps = deps

Slide 79

Slide 79 text

Dependency Management, part 3 ./app/build.gradle ./build.gradle ./versions.gradle

Slide 80

Slide 80 text

Dependency Management, part 3 ./build.gradle buildscript { apply from: ‘./versions.gradle' }

Slide 81

Slide 81 text

Dependency Management, part 3 ./versions.gradle ./build.gradle ./app/build.gradle

Slide 82

Slide 82 text

Dependency Management, part 3 ./app/build.gradle dependencies { implementation deps.dagger.runtime

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

WHOA!

Slide 85

Slide 85 text

Dependency Management, part 4 ./buildSrc/src/main/java/../Deps.java

Slide 86

Slide 86 text

Dependency Management, part 4 ./buildSrc/src/main/java/../Deps.java package com.example.gradle; public class Deps { public static final String guava = "com.google.guava:guava:18.0"; }

Slide 87

Slide 87 text

Dependency Management, part 4 ./app/build.gradle import com.example.Deps; dependencies { implementation Deps.guava ./buildSrc/src/main/java/../Deps.java

Slide 88

Slide 88 text

Dependency Management, part 5

Slide 89

Slide 89 text

Dependency Management, part 5 ./buildSrc/src/main/java/../Deps.kt object Libs { val guava = “com.google.guava:guava:18.0”

Slide 90

Slide 90 text

Dependency Management, part 5 ./buildSrc/build.gradle.kts plugins { `kotlin-dsl` } ./buildSrc/src/main/java/../Deps.kt

Slide 91

Slide 91 text

Other Constants

Slide 92

Slide 92 text

Other Constants ./build.gradle ext { minSdkVersion = 18

Slide 93

Slide 93 text

Other Constants ./build.gradle ./versions.gradle def build_versions = [:] build_versions.min_sdk = 14 ext.build_versions = build_versions

Slide 94

Slide 94 text

Other Constants ./build.gradle ./versions.gradle ./buildSrc/src/main/java/../Deps.java public class Deps { public static final String minSdk = “14";

Slide 95

Slide 95 text

No content

Slide 96

Slide 96 text

Sharing

Slide 97

Slide 97 text

No content

Slide 98

Slide 98 text

YUM!

Slide 99

Slide 99 text

apply plugin: 'kotlin-kapt'

Slide 100

Slide 100 text

apply plugin: 'kotlin-kapt' apply from: “./versions.gradle"

Slide 101

Slide 101 text

apply from: “./versions.gradle"

Slide 102

Slide 102 text

Project Modules App Libraries

Slide 103

Slide 103 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 104

Slide 104 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 105

Slide 105 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 106

Slide 106 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 107

Slide 107 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 108

Slide 108 text

feature1- domain feature2- domain

Slide 109

Slide 109 text

feature1- domain feature2- domain ./f1-domain/ build.gradle dependencies { ... }

Slide 110

Slide 110 text

feature1- domain feature2- domain ./f1-domain/ build.gradle dependencies { ... } ./f2-domain/ build.gradle dependencies { ... }

Slide 111

Slide 111 text

feature1- domain feature2- domain ./f1-domain/ build.gradle apply from: “/shared- domain.gradle” ./f2-domain/ build.gradle dependencies { ... }

Slide 112

Slide 112 text

feature1- domain feature2- domain ./f1-domain/ build.gradle apply from: “/shared- domain.gradle" ./f2-domain/ build.gradle apply from: “/shared- domain.gradle"

Slide 113

Slide 113 text

feature1- domain feature2- domain ./shared-domain.gradle dependencies { ... } ./f1-domain/ build.gradle ./f2-domain/ build.gradle

Slide 114

Slide 114 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 115

Slide 115 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 116

Slide 116 text

feature1- data feature2- data network ./.../build.gradle apply from: “../shared-domain.gradle” apply from: “../shared-data.gradle”

Slide 117

Slide 117 text

feature1- data feature2- data network ./.../build.gradle ./shared-data.gradle dependencies { ... }

Slide 118

Slide 118 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 119

Slide 119 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 120

Slide 120 text

feature1- presentation feature1- data feature2- presentation feature2- data ui-common network ./shared-android.gradle android { ... }

Slide 121

Slide 121 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 122

Slide 122 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 123

Slide 123 text

App 1 feature1- presentation feature2- presentation App 2 ./shared-variants.gradle android {Ω flavorDimensions “function” productFlavors { ... } }œ configurations { ... }

Slide 124

Slide 124 text

App 1 feature1- presentation feature2- presentation App 2 ./shared-variants.gradle android {Ω... flavorDimensions“function”productFlavors{ ... } }œ configurations { ... }

Slide 125

Slide 125 text

App 1 feature1- presentation feature2- presentation App 2 ./shared-variants.gradle android {Ω... flavorDimensions“function”productFlavors{ ... } }œ configurations { ... } android.variantFilter { ... }

Slide 126

Slide 126 text

App 1 feature1- presentation feature2- presentation App 2 ./shared-variants.gradle android {Ω... flavorDimensions“function”productFlavors{ ... } }œ configurations { ... } android.variantFilter { ... }

Slide 127

Slide 127 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 128

Slide 128 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 129

Slide 129 text

App 1 App 2 ./shared-apps.gradle android { buildTypes { proguardFiles ... testProguardFile ... } } packagingOptions { ... }

Slide 130

Slide 130 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 131

Slide 131 text

App 1 feature1- presentation feature1- data feature2- presentation feature2- data ui-common network App 2 ./shared-test.gradle android { sourceSets { test.java.srcDirs += [“...”] } }

Slide 132

Slide 132 text

App 1 feature1- presentation feature1- data feature1- domain feature2- presentation feature2- data feature2- domain ui-common network App 2

Slide 133

Slide 133 text

feature1- presentation feature1- data feature1- domain ./shared-feature1-tasks.gradle task cleanReports( type: Delete, group: 'Reports') { description "Delete Repots" delete ‘reportsDirectory' }

Slide 134

Slide 134 text

No content

Slide 135

Slide 135 text

Get Organized!

Slide 136

Slide 136 text

No content

Slide 137

Slide 137 text

Get Organized! ./shard-apps.gradle ./shard-android.gr ./shard-domain.gra ./shard-data.gradle ./shard-variants.gradle

Slide 138

Slide 138 text

Get Organized! ./buildscripts/ ./shard-apps.gradle ./shard-android.gradle ./shard-domain.gradle

Slide 139

Slide 139 text

Get Organized! ./settings.gradle include ‘:buildscripts’, ... ./buildscripts/ ./shard-apps.gradle

Slide 140

Slide 140 text

Renaming

Slide 141

Slide 141 text

No content

Slide 142

Slide 142 text

No content

Slide 143

Slide 143 text

\ or /

Slide 144

Slide 144 text

./app/build.gradle

Slide 145

Slide 145 text

./app/app.gradle

Slide 146

Slide 146 text

./lib/lib.gradle ./app/app.gradle

Slide 147

Slide 147 text

./data/data.gradle ./app/app.gradle ./lib/lib.gradle

Slide 148

Slide 148 text

./lib/lib.gradle ./data/data.gradle ./core/core.gradle

Slide 149

Slide 149 text

./data/data.gradle ./core/core.gradle ./util/util.gradle

Slide 150

Slide 150 text

./settings.gradle rootProject.children.each { subproject -> subproject.buildFileName = “${subproject.name}.gradle" }

Slide 151

Slide 151 text

No content

Slide 152

Slide 152 text

No content

Slide 153

Slide 153 text

Renaming ! bash script (github)

Slide 154

Slide 154 text

Renaming ! bash script (github) ! new modules

Slide 155

Slide 155 text

No content

Slide 156

Slide 156 text

Pitfalls*

Slide 157

Slide 157 text

Pitfalls* DON’T DO THIS

Slide 158

Slide 158 text

“core” module

Slide 159

Slide 159 text

“core” module ! For dependency management?

Slide 160

Slide 160 text

“core” module ./module1/module1.gradle dependency { implementation deps.dagger implementation deps.timber implementation reps.rxjava }

Slide 161

Slide 161 text

“core” module ./core/core.gradle dependency { api deps.dagger api deps.timber api reps.rxjava }

Slide 162

Slide 162 text

App Core Library “core” module ./core/core.gradle

Slide 163

Slide 163 text

No content

Slide 164

Slide 164 text

“core” module ! For dependency management? ! Don’t enlarge the surface!

Slide 165

Slide 165 text

“core” module ! For dependency management? ! Don’t enlarge the surface! ! Slower builds

Slide 166

Slide 166 text

“core” module ! For dependency management? ! Don’t enlarge the surface! ! Slower builds ! Shared gradle file instead

Slide 167

Slide 167 text

Nested Modules

Slide 168

Slide 168 text

Nested Modules feature1- presentation feature1- data feature1- domain

Slide 169

Slide 169 text

Nested Modules ./feature1 |-feature1-presentation |-feature1-data |-feature1-domain

Slide 170

Slide 170 text

No content

Slide 171

Slide 171 text

Nested Modules ! Slower reloading project

Slide 172

Slide 172 text

Nested Modules ! Slower reloading project ! Does not show up in Android view

Slide 173

Slide 173 text

Nested Modules ! Slower reloading project ! Does not show up in Android view ! Relative paths

Slide 174

Slide 174 text

If you insist…

Slide 175

Slide 175 text

1. Git History > mkdir feature1 > git mv feature1-domain ./feature1/ feature1-domain ...

Slide 176

Slide 176 text

2. Replace Relative Paths apply from: "../buildscripts/shared- android.gradle"

Slide 177

Slide 177 text

2. Replace Relative Paths apply from: "$BUILDSCRIPTS_DIR/shared- test.gradle"

Slide 178

Slide 178 text

3. Additional Settings implementation project(“:feature1-data“)

Slide 179

Slide 179 text

3. Additional Settings implementation project(“:feature1:feature1-data“)

Slide 180

Slide 180 text

3. Additional Settings implementation project(“:feature1-data“) ./settings.gradle include ‘:feature1-data' project (':feature1-data').projectDir = new File('./feature1/feature1-data')

Slide 181

Slide 181 text

Resources https://google.github.io/android-gradle-dsl/current/ https://docs.gradle.org/current/dsl/index.html https://gradle.org/releases/ https://gradle.org/guides/ http://www.developerphil.com/ https://developer.android.com/studio/build/optimize-your- build.html
 https://github.com/cliveleehere/multimodulegradle
 Google I/O 2017 “What's New in Android Development Tools”

Slide 182

Slide 182 text

Thanks! @CliveLeeHere