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
Finally, settings.gradle
Whew, build.gradle
was quite a big file! Hope, you’re not tired yet :] The next file will be quite short – move to the settings.gradle file in the root directory. Its contents should look as follows:
include ':app'
In this file, you should define all of your project’s modules by name. Here we have only one module – app. In a large, multi-module project, this file can have a much longer list.
Groovy vs. Kotlin in Gradle
Kotlin’s popularity is growing every day. Besides Android apps, you can also write back-end web code, front-end web code, and even iOS apps using Kotlin! Recently, Gradle announced Kotlin language support for writing build scripts. The Gradle Kotlin DSL is still in pre-release and requires nontrivial setup, and won’t be covered in this tutorial. However, it’s quite promising and surely worth waiting for its release.
Why Kotlin
You may be wondering, why would you use Kotlin for writing Gradle scripts?
First of all, Kotlin is a statically typed language (Groovy is dynamically typed), which allows for conveniences like autocompletion, better refactoring tools and source-code navigation. You can work in script files just you would with Kotlin classes, with all support of Android Studio you’re used to. Moreover, autocompletion will prevent you from making typos :].
Secondly, it’s practical to work with a single language across your app and your build system.
Mastering the build: Gradle Commands
To execute Gradle commands, you can use both the command line and Android Studio. It’s better to start from the former one to get acquainted more deeply about what’s going on. So, how can you start working with Gradle commands? Pretty easy – use gradlew.
What is gradlew
gradlew is the Gradle Wrapper. You don’t need to worry about installating Gradle on your computer – the wrapper will do that for you. Even more, it’ll allow you to have different projects built with various versions of Gradle.
Open your command line and move to the root directory of the starter project:
cd path/to/your/Android/projects/SocializifyStarter/
gradlew tasks
After that, execute the following command:
./gradlew tasks
You’ll see a list containing all available tasks:
> Task :tasks ------------------------------------------------------------ All tasks runnable from root project ------------------------------------------------------------ Android tasks ------------- androidDependencies - Displays the Android dependencies of the project. signingReport - Displays the signing info for each variant. sourceSets - Prints out all the source sets defined in this project. Build tasks ----------- assemble - Assembles all variants of all applications and secondary packages. assembleAndroidTest - Assembles all the Test applications. assembleDebug - Assembles all Debug builds. assembleRelease - Assembles all Release builds. ... Build Setup tasks ----------------- init - Initializes a new Gradle build. wrapper - Generates Gradle wrapper files. Help tasks ---------- ... Install tasks ------------- ... Verification tasks ------------------ ... lint - Runs lint on all variants. ... To see all tasks, run gradlew tasks --all To get more detail about task, run gradlew help --task <task>
These commands exist to help you with tasks like project initialization, building, testing and analyzing. If you forget a specific command, just execute ./gradlew tasks
to refresh your memory.
gradlew assemble
Now skim the list of commands again, and find commands starting with ‘assemble’ under the Build tasks
section. Run the first command:
./gradlew assemble
Below is the output of executing this command:
> Task :app:compileDebugKotlin Using kotlin incremental compilation > Task :app:compileReleaseKotlin Using kotlin incremental compilation BUILD SUCCESSFUL in 29s 52 actionable tasks: 52 executed
From the output, it’s apparent that Gradle compiled two versions of the app – debug and release.
Verify this by changing to the build output directory:
cd app/build/outputs/apk/
To review the contents of a directory run the following command:
ls -R
The ls
command displays all files and directories in the current directory. The -R
parameter forces this command to execute recursively. In other words, you’ll not only see the contents of your current directory but also of child directories.
You’ll get the following output:
debug release ./debug: app-debug.apk output.json ./release: app-release-unsigned.apk output.json
As you see, Gradle generated both debug and release apks.
gradlew lint
Move back to the root directory:
cd ../../../..
Run the following command:
./gradlew lint
The lint
command, and any commands which start with ‘lint’, analyzes the whole project looking for various mistakes, typos or vulnerabilities. The first command will find all the issues in a project with both critical and minor severity.
You’ll get the output with the count of issues found:
> Task :app:lint Ran lint on variant debug: 47 issues found Ran lint on variant release: 47 issues found Wrote HTML report to file:///Users/username/path/to/your/Android/projects/SocializifyStarter/app/build/reports/lint-results.html Wrote XML report to file:///Users/username/path/to/your/Android/projects/SocializifyStarter/app/build/reports/lint-results.xml
Review the report by typing the following on Mac:
open app/build/reports/lint-results.html
or on Linux:
xdg-open app/build/reports/lint-results.html
The default browser on your computer will open with the specified file:
You can inspect all the issues found with code snippets and an expanded description of a possible solution. However, don’t focus too much on all of these issues – pay attention to the critical ones and fix them immediately. Minor issues shouldn’t necessarily warrant a refactoring, depending upon your teams guidelines and processes.
Managing Dependencies
Now it’s time to make changes to the application itself. Build and run the starter project:
This screen shows a user’s profile – name, followers, photos, etc. However, something’s missing – an avatar! In order to load an avatar from a URL, we’ll use a third-party library in our application, namely, we’ll use Picasso.
Picasso is described as a “A powerful image downloading and caching library for Android”. To get started with Picasso, you need to add it as a dependency to your project.
First, create a file named dependencies.gradle in the root directory of the project. You’ll use this file as the means of identifying all the project dependency versions in one place. Add the following to this file:
ext { minSdkVersion = 17 targetSdkVersion = 27 compileSdkVersion = 27 buildToolsVersion = "26.0.2" kotlinVersion = "1.1.51" supportVersion = "27.0.1" picassoVersion = "2.5.2" }
Open the project-level build.gradle file (the one in the root directory, not the one in the app directory!) and add the following line on the top of the file:
apply from: 'dependencies.gradle'
Now you can use the properties you specified in the dependencies.gradle file in your other project build files like this:
app module-level build.gradle
android { compileSdkVersion rootProject.compileSdkVersion buildToolsVersion rootProject.buildToolsVersion defaultConfig { applicationId "com.raywenderlich.socializify" minSdkVersion rootProject.minSdkVersion targetSdkVersion rootProject.targetSdkVersion versionCode 1 versionName "1.0" } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation "com.android.support:appcompat-v7:$rootProject.supportVersion" implementation "com.android.support:design:$rootProject.supportVersion" implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$rootProject.kotlinVersion" }
Add the following line, to include Picasso, in your module-level build.gradle file (in the app directory!) inside the dependencies
block:
implementation "com.squareup.picasso:picasso:$rootProject.picassoVersion"
When you modify build files, you’ll be prompted to sync the project:
Don’t be afraid to re-sync your project. It takes a short while until the sync is completed, and the time it takes gets longer when you have more dependencies and more code in your project.
When the project syncing is complete, open ProfileActivity
and add this function to load a user’s avatar:
// 1
private fun loadAvatar() {
// 2
Picasso.with(this).load("https://goo.gl/tWQB1a").into(avatar)
}
If you get build errors, or if you’re prompted to resolve the imports in Android studio, be sure the following imports are included:
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_profile.*
Here’s a step-by-step explanation of what’s going on:
- You define a Kotlin function
loadAvatar()
- Picasso needs an instance of a
Context
to work, so you must callwith(context: Context!)
, passing in the current Activity as the Context. This returns an instance of the Picasso class. Next, you specify the URL of an image you want to load with theload(path: String!)
method. The only thing left is to tell Picasso where you want this image to be shown by calling theinto(target: ImageView!)
method.
Add this function invocation in the onCreate(savedInstanceState: Bundle?)
function of your ProfileActivity
:
loadAvatar()
The last step, which even senior Android developers tend to forget, is to add the android.permission.INTERNET
permission. If you forgot to add this permission, Picasso simply can’t download the image and it’s hard to spot any error. Go to the AndroidManifest.xml file and add the following permission above the application
tag:
<uses-permission android:name="android.permission.INTERNET" />
That’s all you need to show the user’s avatar. Build and run the project: