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.

4.8 (16) · 1 Review

Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

What is a Build Variant

From the output above, what you’ve actually generated are different build variants, which are a combination of build types – debug and release and build flavors – free and paid. That is to say, you have four possible build variants – paidDebug, paidRelease, freeDebug and freeRelease.

Great! You’ve got two different build flavors, however, differing names isn’t enough for you to profit from. Instead, you’ll configure your app’s behavior based on the flavor type!

Declare a constant for the paid flavor right below the declaration of ProfileActivity class:

companion object {
  const val PAID_FLAVOR = "paid"
}

Add the following function to ProfileActivity:

private fun isAppPaid() = BuildConfig.FLAVOR == PAID_FLAVOR

You can now check if a user is using a paid version of the app. Depending on the result of this check, you’ll enable or disable some functionality visible to your user so they can clearly see what version they’re using in-app.

Add these strings to the strings.xml file:

<string name="free_app_message">Hi! You\'re using the free version of the application</string>
<string name="paid_app_message">Hi! Congratulations on buying
        the premium version of the application</string>

Add the following functions below isAppPaid():

private fun showMessage() {
  val message = if (isAppPaid()) R.string.paid_app_message else R.string.free_app_message
  Toast.makeText(this, message, Toast.LENGTH_LONG).show()
}

private fun togglePhotosVisibility() {
  extraPhotos.visibility = if (isAppPaid()) View.VISIBLE else View.GONE
  restriction.visibility = if (isAppPaid()) View.GONE else View.VISIBLE
}

Add these functions invocations in the onCreate(savedInstanceState: Bundle?) function:

showMessage()
togglePhotosVisibility()

Now, your user will see a different greeting message and will be able to view the whole photo feed or just some of the photos depending on the app version.

Select the freeRelease build variant in the window below:

Build variant panr

Build and run the project (you may first need to choose the app build configuration in the drop-down next to the Run button):

Free app

You should see that the functionality of the app is restricted and the message with a corresponding text is shown.

Select the paidRelease option, and run the app again:

Paid app

If a user buys your app, they’ll be able to access its full functionality.

Creating Tasks

Sometimes you need your build system to do something more complicated or customize the build process in some way. For example, you may want Gradle to output an APK file containing the build date in its name. One possible solution to this is to create a custom Gradle task.

Add the following code in your module-level build.gradle file at the same level as android block:

// 1
task addCurrentDate() {
    // 2
    android.applicationVariants.all { variant ->
        // 3
        variant.outputs.all { output ->
            // 4
            def date = new Date().format("dd-MM-yyyy")
            // 5
            def fileName = variant.name + "_" + date + ".apk"
            // 6
            output.outputFileName = fileName
        }
    }
}

Here’s what’s is going on:

  1. You define an addCurrentDate() task.
  2. You iterate through all the output build variants.
  3. You iterate over all the APK files.
  4. You create an instance of Date and format it.
  5. You create a new filename appending the current date to the initial name.
  6. You set the new filename to current APK file.

Now you need to execute this task at a specific point of the build process. Add the following code below the task addCurrentDate() block:

gradle.taskGraph.whenReady {
    addCurrentDate
}

The task specified in the whenReady block will be called once when the current graph is filled with tasks and ready to start executing them. Here, you specify the name of your addCurrentDate task.

Now, go back to the command line and make sure you’re in the root directory. Run the following command to assemble a build:

./gradlew assemblePaidRelease

After the task has completed, go to the output directory and check if the build has been named correctly:

cd app/build/outputs/apk/paid/release/
ls

You should get a similar output:

output.json paidRelease_12-11-2017.apk

If your task executed correctly, all your builds will be named with this convention.

Creating Custom Plugins

Usually it’s a good idea to factor out your code into smaller pieces so it can be reused. Similarly, you can factor out your tasks into a custom behavior for the building process as a plugin. This will allow you to reuse the same behavior in other modules you may add to your project.

To create a plugin, add the following class below the addCurrentDate task in the module-level build.gradle file:

class DatePlugin implements Plugin<Project> {
    void apply(Project project) {
        project.task('addCurrentDatePluginTask') {
            project.android.applicationVariants.all { variant ->
                variant.outputs.all { output ->
                    def date = new Date().format("dd-MM-yyyy")
                    def fileName = variant.name + "_" + date + ".apk"
                    output.outputFileName = fileName
                }
            }
        }
    }
}

Add the name of your plugin at the top of this file along with the other apply plugin definitions:

apply plugin: DatePlugin

Conceptually, the code in the plugin is doing the same thing as the task – you’re still modifying the names of the output files. The only difference is that you define a class which implements Plugin and its single method apply(Project project).

In this method, you’re adding your plugin to the target – Project. By calling the task(String name, Closure configureClosure) method you’re creating a new task with a specific name and behavior and adding it to the project.

Now modify the whenReady block to call a new task:

gradle.taskGraph.whenReady {
    addCurrentDatePluginTask
}

and remove the task addCurrentDate() block you added earlier.

Now you can verify that this plugin is doing the same thing like the task. Assemble a new build and verify the APK filename:

./gradlew assemblePaidRelease
cd app/build/outputs/apk/paid/release/
ls

output.json paidRelease_12-11-2017.apk

Where to Go From Here

You can download the final project here.

The Android Gradle plugin 3.0 contains some significant differences from previous versions. So it’s worth reviewing the changelog.

Also, if you’re insterested in the Gradle Kotlin DSL, here you can find a list of usage examples to get familiar with it.

I hope you’ve enjoyed this Getting Started with Gradle tutorial! Don’t forget to leave your feedback and feel free to ask any questions in the comments below :]

Contributors

Meng Taing

Tech Editor

Vijay Sharma

Final Pass Editor

Joe Howard

Team Lead

Over 300 content creators. Join our team.