Gradle Tutorial for Android: Getting Started
In this Gradle Build Script tutorial you’ll learn the basic syntax in build.gradle files generated by Android Studio. You’ll also learn about gradlew tasks, build types, product flavors, build variants, and how to add additional information such as the date to the APK file name. By Irina Galata.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Gradle Tutorial for Android: Getting Started
35 mins
- What is Gradle?
- Getting Started
- Project-level build.gradle
- Module-level build.gradle
- Finally, settings.gradle
- Groovy vs. Kotlin in Gradle
- Why Kotlin
- Mastering the build: Gradle Commands
- What is gradlew
- gradlew tasks
- gradlew assemble
- gradlew lint
- Managing Dependencies
- Gradle Dependency Configurations
- Ready to Publish: Working with Product Flavors and Build Types
- Build Types
- Build Signing
- Build Flavors
- What is a Build Variant
- Creating Tasks
- Creating Custom Plugins
- Where to Go From Here
Gradle Dependency Configurations
The implementation
keyword you previously used is a dependency configuration, which tells Gradle to add Picasso in such way, that it’s not available to other modules. This option significantly speeds up the build time. You’ll use this keyword more often than others.
In some other cases, you may want your dependency to be accessible to other modules of your project. In those cases, you can use the api
keyword.
Other options include runtimeOnly
and compileOnly
configurations, which mark a dependency’s availability during runtime or compile time only.
Ready to Publish: Working with Product Flavors and Build Types
Your app is ready, and you’re thinking of ways to profit from it :]
One solution might be to have multiple versions of your app: a free and paid version. Luckily for you, gradle supports this at the build level, allowing you to define the boundaries of different build types. However, before getting started, you need to understand how Gradle allows you to work with different app versions.
Build Types
By default, there are two build types – debug and release. The only difference between them is the value of the debuggable
parameter. In other words, you can use the debug version to review logs and to debug the app, while the release one is used to publish your app to the Google Play Store. You can configure properties to the build types by adding the following code in the android
block of your module-level build.gradle file:
buildTypes { release { } debug { } }
In the debug
and release
blocks you can specify the type-specific settings of your application.
Build Signing
One of the most important configurations of the build is its signature. Without a signature, you’ll be unable to publish your application, since it’s necessary to verify you as an owner of the specific application. While you don’t need to sign the debug build – Android Studio does it automatically – the release build should be signed by a developer.
When your keystore is ready, add the code below in the android
block and above the buildTypes
block (the order of declaration matters) of the module-level build.gradle file:
signingConfigs { release { storeFile file("path to your keystore file") storePassword "your store password" keyAlias "your key alias" keyPassword "your key password" } }
In the signingConfigs
block, you specify your signature info for the build types. Pay attention to the keystore file path. It should be specified with respect to the module directory. In other words, if you created a keystore file in the module directory and named it “keystore.jks”, the value you should specify will be equal to the name of the file.
Update the buildTypes
block to sign your release build automatically:
release { signingConfig signingConfigs.release }
Then be sure to keep keystorePassword.gradle
ignored by your version control system. Other techniques include keeping the password in an OS-level environment variable, especially on your remote Continuous Integration system, such as CircleCI.
- Once you’ve published your app to the Google Play Store, subsequent submissions must use the same keystore file and password, so keep them safe.
- Be sure NOT to commit your keystore passwords to a version control system such as GitHub. You can do so by keeping the password in a separate file from
build.gradle
, saykeystorePassword.gradle
in aSigning
directory, and then referencing the file from the app module-levelbuild.gradle
via:apply from: "../Signing/keystorePassword.gradle
- Once you’ve published your app to the Google Play Store, subsequent submissions must use the same keystore file and password, so keep them safe.
- Be sure NOT to commit your keystore passwords to a version control system such as GitHub. You can do so by keeping the password in a separate file from
build.gradle
, saykeystorePassword.gradle
in aSigning
directory, and then referencing the file from the app module-levelbuild.gradle
via:apply from: "../Signing/keystorePassword.gradle
Then be sure to keep keystorePassword.gradle
ignored by your version control system. Other techniques include keeping the password in an OS-level environment variable, especially on your remote Continuous Integration system, such as CircleCI.
apply from: "../Signing/keystorePassword.gradle
Build Flavors
In order to create multiple versions of your app, you need to use product flavors. Flavors are a way to differentiate the properties of an app, whether it’s free/paid, staging/production, etc.
You’ll distinguish your app flavors with different app names. First, add the following names as strings in the strings.xml file:
<string name="app_name_free">Socializify Free</string>
<string name="app_name_paid">Socializify Paid</string>
And remove the existing:
<string name="app_name">Socializify</string>
Now that the original app_name
string is no longer available, edit your AndroidManifest.xml file and replace android:label="@string/app_name"
with android:label="${appName}"
inside the application
tag.
Add the following code in the android
block of your module-level build.gradle file:
// 1 flavorDimensions "appMode" // 2 productFlavors { // 3 free { // 4 dimension "appMode" // 5 applicationIdSuffix ".free" // 6 manifestPlaceholders = [appName: "@string/app_name_free"] } paid { dimension "appMode" applicationIdSuffix ".paid" manifestPlaceholders = [appName: "@string/app_name_paid"] } }
- You need to specify the flavor dimensions to properly match the build types. In this case, you need only one dimension – the app mode.
- In the
productFlavors
specify a list of flavors and their settings. In this case,free
, andpaid
- Specify the name of the first product flavor –
free
. - It’s mandatory to specify the
dimension
parameter value. Thefree
flavor belongs to theappMode
dimension. - Since you want to create separate apps for free and paid functionality, you need them to have different app identifiers. The
applicationIdSuffix
parameter defines a string that’ll be appended to theapplicationId
giving your app unique identifiers. - The
manifestPlaceholders
allows you to modify properties in your AndroidManifest.xml file at build time. In this case, modify the application name depending on its version.
Sync your project with Gradle again. After the project sync, run the tasks
command, and see if you can spot what’s changed:
./gradlew tasks
You’ll get a similar list of tasks to the one you got when you ran this command first time:
... Build tasks ----------- ... assembleDebug - Assembles all Debug builds. assembleFree - Assembles all Free builds. assemblePaid - Assembles all Paid builds. assembleRelease - Assembles all Release builds. ...
Spot the difference? If you pay attention to the tasks under the Build tasks
section, you should have some new ones there. You now have separate commands for each build type and build flavor.
Remove the generated output folder from previous ./gradlew assemble
task so that you can see the clear difference before and after adding buildTypes
and productFlavors
. Run the command:
rm -rf app/build/outputs/apk
Then
./gradlew assembleDebug
When the command completes, check the output directory:
cd app/build/outputs/apk
ls -R
You’ll get something like this:
free paid ./free: debug ./free/debug: app-free-debug.apk output.json ./paid: debug ./paid/debug: app-paid-debug.apk output.json
You should have two builds generated – freeDebug
and paidDebug
.