ID Android TechTalk Series #6 : Google Service and Gradle - Anton Nurdin Tuhadiansyah

Preview:

Citation preview

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/

Anton Nurdin TSenior Software Engineer, Xendit

anton46.com

THANK YOU