id android techtalk series #6 : google service and gradle - anton nurdin tuhadiansyah
TRANSCRIPT
Anton Nurdin TSenior Software Engineer, Xendit
anton46.com
DEEP UNDERSTANDING ABOUT
What is Gradle?
Android Build System
Android Build System
antMaven
Gradle
SBT
buck
Build Process
Multi-Language
Resource/Code Generation
Platform Diversity
Why Gradle?1. Powerful Build System
- Declarative, Flexible- Imperative Customization - Tooling API
2. Build System Toolkit- Plugins create own DSL, APIs, IDE integration
3. Free/Open Source
StructureSettings File
- settings.gradle
StructureSettings File
- settings.gradle
Top-level Build File
Top-level Build File
buildscript { repositories { jcenter() }
dependencies { classpath 'com.android.tools.build:gradle:2.0.0' } }
allprojects { repositories { jcenter() } }
build.gradle
StructureSettings File
- settings.gradle
Top-level Build File
StructureSettings File
- settings.gradle
Top-level Build File
Module-level Build File
apply plugin: 'com.android.application'
android { compileSdkVersion 23 buildToolsVersion "23.0.3"
defaultConfig { ... }
buildTypes { ... }
productFlavors { ... } }
dependencies { ... }
Module-level Build File
build.gradle
Gradle Tasksassemble
check
build
clean
assemble + check
assembleDebug + assembleRelease
connectedCheckdeviceCheck
COSTUMIZATION
Basic Customization
android { compileSdkVersion 23 buildToolsVersion "23.0.3"
defaultConfig { minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } }
build.gradle
Basic Customization
def getVersionCode() { def code = ... return code; }
android { defaultConfig { versionCode getVersionCode()
... } }
build.gradle
Basic Customizationandroid { defaultConfig {
applicationId “com.example.app” minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0"
applicationVariants.all { variant -> variant.outputs.each { output -> def file = output.outputFile def fileName = file.name.replace(".apk", "-v" + versionName + "-c" + versionCode + ".apk") output.outputFile = new File(file.parentFile, fileName) } } } }
build.gradle
Basic Customization
app-debug-v1.0-c1.apk
app-release-v1.0-c1.apk
Build Types- Build / Packaging customization
• Debuggable flag • ProGuard • Signing Configuration • Source / Resource Overlay\
- Debug and release prebuilt
Build Types
android { buildTypes { debug { applicationIdSuffix '.debug' versionNameSuffix '-DEBUG' } beta { applicationIdSuffix '.beta' versionNameSuffix '-BETA' } } }
build.gradle
Build Types : Source Folder
src/main/AndroidManifest.xml src/main/java src/main/resource src/main/res src/main/assets src/main/aidl src/main/rs src/main/jni
src/debug/... src/release/... src/beta/...
src/androidTest/java src/androidTest/resource src/androidTest/res src/androidTest/assets src/androidTest/aidl src/androidTest/rs src/androidTest/jni
Gradle Tasksassemble
check
build
clean
assemble + check
assembleDebug + assembleRelease + assembleBeta
connectedCheckdeviceCheck
Signing Configuration
\
android { signingConfigs { release { storeFile file('<name>.keystore') keyAlias 'keyAlias' keyPassword 'keyPassword' storePassword 'storePassword' } } }
build.gradle
Debuggable Release Builds
\
android { signingConfigs { debugRelease.intiWith(buildTypes.release) debugRelease { debuggable true applicationIdSuffix '.debugrelease' signingConfig signingConfigs.debug } } }
build.gradle
DEPENDENCIES
Dependency Scope: Java Projects
compile
\
runtime
testCompiletestRuntime
Dependency Scope: Android Projects
compile
\
runtime
testCompiletestRuntime
compile
package
androidTestCompileandroidTestPackage
Local Dependencies
\
android { ... }
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) }
build.gradle
Remote Dependencies
\
repositories { jcenter() }
android { ... }
dependencies { compile 'com.android.support:appcompat-v7:23.2.1'
}
build.gradle
Multi-Project Setup
\
settings.gradle
include ':app' include ':libraries:lib1' include ':libraries:lib2'
MyProject/ | settings.gradle + app/ | build.gradle
+ libraries/ + lib1/ | build.gradle
+ lib2/ | build.gradle
Project Dependencies
\
android { ... }
dependencies { compile project(‘:libraries:lib1’)
}
build.gradle
Android Library Project
\
apply plugin: 'com.android.library'
android { compileSdkVersion 23 buildToolsVersion '23.0.1' }
build.gradle
Android Library- Binary Bundle (.aar)
• Uploadable to repositories
\- Support for
• assets • Proguard rules • Custom Lint rules • . . .
BUILD VARIANTS
Product Flavors- Different versions of the same application
• Paid vs Free • Multi-APK support in Google Play
\- Different Dimension(s) than BuildTypes
Android Library Project
\
android { productFlavors { flavour1 { applicationId "com.example.flavour1" minSdkVersion 16 } flavour2 { applicationId "com.example.flavour2" } } }
build.gradle
Build Types : Source Folder
src/main/AndroidManifest.xml src/main/java src/main/resource src/main/res src/main/assets src/main/aidl src/main/rs src/main/jni
src/androidTest/java src/androidTest/resource src/androidTest/res src/androidTest/assets src/androidTest/aidl src/androidTest/rs src/androidTest/jni
src/debug/... src/release/... src/beta/... src/flavor1/... src/androidTestFlavor1/...
Variant = Build Type + Product Flavor(s)
No Flavors :
\debug release
- debug release
- - -
Variant = Build Type + Product Flavor(s)
No Flavors :
\
debug release
- debug release
- - -
With Flavors : debug release
Flavor1 Flavor1Debug Flavor1Release
Flavor2 Flavor2Debug Flavor2Release
Build Variants : Source Code
Multiple source folders, single output
src/main/java
src/debug/java
src/free/java
Build Variants : Resource
Overlays
src/main/res
src/debug/res
src/free/res
Build Variants : Signing Configuration
Priority Order
android.defaultConfig.signingConfig
android.buildTypes.release.signingConfig
android.productFlavors.free.signingConfig
Build Variants : Package Name
Overlays + Suffix
android.defaultConfig.packageName
android.productFlavors.free.signingConfig
+ android.buildTypes.debug.packageNameSuffix
src/main/AndroidManifest.xml
Build Variants : Proguard
android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
productFlavors { flavor2 { proguardFile 'flavor2-rules.pro' } } }
build.gradle
Res / Code Generation
buildConfigField
resValue
build.gradleandroid { buildTypes { debug { buildConfigField "String", "SERVER_URL", '"http://staging.example.co"' resValue "string", "facebook_app_id", '"12345678910'
... } release { buildConfigField "String", "SERVER_URL", '"https://example.co"' resValue "string", "facebook_app_id", '"0987654321'
... } } }
Res / Code Generation
PERFORMACE
GRADLE IS FAST
GRADLE IS FAST
200 Projects
grade clean assemble —-parallel 7s
• Android Studio IDE (Android Tooling Team) • Gradle Android Plugin (Android Tooling Team) • Gradle Flatform (Gradle Team) • Android Tooling (Android Platform Team)
Toolchain
BOTLENECK
Clean Install (61.9s)
1%8%
46% 27%
3%14% Install (8.89s)
After Dexing (2.06s)Dex (16.67s)Pre-Dex (28.54s)Before Dexing (5.04)Configuration (0.65)
Install After Code Change (33.31s)
2%15%
50%
6%
27% Install (8.89s)After Dexing (2.06s)Dex (16.67s)Before Dexing (5.04s)Configuration (0.65s)
PRE-DEXINGDEXING
Hint• Enable the Gradle daemon and parallel build
dexOptions { incremental true }
• Incremental dexing
~/.gradle/gradle.properties
org.gradle.daemon=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx1024m org.gradle.java.home=/path/to/jvm
• Offline Mode• Separate project into modules
https://source.android.com/source/jack.html
Jack Compiler
http://gradle.org/training/