An advance build toolkit Gradle in Android Part-2
Welcome to Part 2 of the Gradle Tutorial. This part builds on Part 1, where we looked at basic understanding of build tools and Gradle features. In this article will discuss more on Gradle customization and its configuration with Android project.
Customize
build configurations
Gradle customization and proper configuration can improve your
Android development experience and speed.
A typical Android studio project has a project level build.gradle
file and as many module-level build.gradle as there are modules.
Gradle and the Android plugin help you to configure lots of aspects
of your build like: Build Types, Product Flavors, Build Variants, Manifest
Entries, Dependencies, Signing of app, Obfuscation Rules, Multiple APK Support
etc.
Let’s have look how to configure all of these and what all the
benefit you can achieve via this customization:
Configure Build
Types
For example, you want debug
builds for developers, client builds
that you share with our clients at the end of a sprint, and release builds that you upload to the
Play Store.
This is because you want certain features like logging or debugging
enabled only during your development which you don’t want in the release build
for security. So you can achieve this by using build type.
You can create and configure build types in the module-level
build.gradle file using buildTypes
block. When you create a new module, Android Studio automatically creates the
debug and release build types for you.
android {
...
defaultConfig {...}
buildTypes {
debug {
debuggable true
shrinkResources
false
proguardFile
'../debug-rules.pro'
}
client {
debuggable true
shrinkResources
true
proguardFile
'../client-proguard-rules.pro'
}
release {
debuggable false
minifyEnabled
true
shrinkResources
true
proguardFiles
getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig
signingConfigs.release
}
}
}
Configure Product
Flavors
You can use the productFlavors
block in your module-level build.gradle file to define different variants of
your product.
android {
...
defaultConfig {...}
buildTypes {...}
productFlavors {
prodFree {
buildConfigField
"String", "Flavour", "FREE"
versionName =
"1.0"
}
prodPaid {
buildConfigField
"String", "Flavour", "PAID"
versionName =
"2.0"
}
mock {
buildConfigField
"String", "Flavour", "MOCK"
versionName =
"3.0"
}
}
}
Build Variants
A build variant is a cross product of a build type and product
flavor, and is the configuration Gradle uses to build your app. As you see
above our possible build variants would be:
debugProdFree , clientProdFree, releaseProdFree
debugProdPaid, clientProdPaid, releaseProdPaid
debugMock, clientMock, releaseMock
Configure Signing
Keys
When you have multiple build types, another thing you may want to
do is use different signing keys for different build types. It is
obvious that your signing keys would be different for different builds and you won’t
want to edit your build.gradle file whenever you want to do a debug, client or release
build.
To achieve this you can use the signingConfigs block in your module-level build.gradle file.
android {
...
defaultConfig {...}
// Define signing keys
signingConfigs {
debug {
storeFile
file('../keystore/debug.keystore')
}
client {
storeFile
file('../keystore/client.keystore')
}
release {
storeFile
file('../keystore/release.keystore')
}
}
// Configure signing
base on build types
buildTypes {
debug {
signingConfig
signingConfigs.debug
...
}
client {
signingConfig
signingConfigs.debug
...
}
release {
signingConfig
signingConfigs.release
...
}
}
}
Configure ProGuard Rules
You can specify different ProGuard rules file for each build type
or variant. To make smaller APK file, you should enable shrinking to remove
unused code and resources in your release build. The build system can run
ProGuard to shrink and obfuscate your classes during the build process.
You can again go through Build Type section, and notice that we
already define different Proguard Rules for different build types. Same you can
also configure for different build variant.
Configure Dependencies
Gradle makes easy to include external binaries or other library
modules to your build as dependencies. The dependencies can be located on your
machine or in a remote repository, and any transitive dependencies they declare
are automatically included as well. Dependencies are usually managed at the
Module-level inside dependencies block
in build.gradle file.
android {
...
defaultConfig {...}
buildTypes {...}
productFlavors {...}
}
dependencies {
// Dependency on a local
library module
compile
project(":mylibrary")
// Dependency on local
binaries
compile fileTree(dir:
'libs', include: ['*.jar'])
// Dependency on a
remote binary
compile
'com.android.support:appcompat-v7:25.0.0'
}
Dependency
types
You can specify dependency configuration as:
Dependencies for test cases
testCompile - Compile dependency for local tests
androidTestCompile - Compile dependency for instrumented tests
Dependencies for different library variants to different app
variants
debugCompile – Debug compile dependency for library variant
releaseCompile – Release compile dependency for library variant
When your dependencies are located at remote repository then you
have to specify the repository location in the repositories block of your top-level build.gradle file. By default,
Android Studio declare JCenter as the repository location. You can specify
different repository location as mentioned below-
// Default JCenter as the repository location
allprojects {
repositories {
jcenter()
}
}
// For Maven central repository add mavenCentral(), or for a local
repository use mavenLocal():
allprojects {
repositories {
jcenter()
mavenCentral()
mavenLocal()
}
}
// Specific repositories as follows:
allprojects {
repositories {
jcenter {
url
'http://jcenter.bintray.com:80'
}
maven {
url
"file://local/repo/"
}
ivy {
url
"https://repo.example.com/ivy"
}
}
}
|
Source set
Gradle has many default configurations
so that we don´t need to rewrite it every time we start a project. For
instance, any module’s src/main/ source set includes the code and
resources used by all its build variants. But we can alter this the way we want
very
easily from the sourceSets block:
src/main/
This source set includes code and
resources common to all build variants.
src/buildType/
Create this source set to include code
and resources only for a specific build type.
src/productFlavor/
Create this source set to include code
and resources only for a specific product flavor.
android {
...
defaultConfig {...}
buildTypes {...}
productFlavors {...}
sourceSets {
main.java.srcDirs = ['src/main/java']
// Socurce set based on product flavour
prodFree.java.srcDirs = ['src/free/java']
prodPaid.java.srcDirs = ['src/paid/java']
prodFree.res.srcDirs = ['src/free/res']
prodPaid.res.srcDirs = ['src/paid/res']
}
}
android {
...
defaultConfig {...}
buildTypes {...}
productFlavors {...}
sourceSets {
main.java.srcDirs = ['src/main/java']
// Socurce set based on build variant
releaseProdFree.res.srcDirs = ['src/free/res']
releaseProdPaid.res.srcDirs = ['src/paid/res']
}
}
Conclusion
As you can see Gradle is a very powerful
build tool. With this article I have described a small part of customization that
you can do with it. Hopefully I will come up with more interesting on this.
To find more interesting topics on Software development follow
me at https://medium.com/@ankit.sinhal.
Twitter:
https://twitter.com/ankitsinhal
Comments
Post a Comment