avatarFaheem un nisa

Summary

This context discusses the basics of Gradle, a build system, and its language, Groovy, and explains the types of Gradle files and the structure of gradle scripts.

Abstract

The context begins with an introduction to Gradle, a build system used in software development, and its language, Groovy. It explains that Gradle scripts are written in Groovy, a JVM language that is similar to Java but with a more concise syntax. The context then goes on to explain the types of Gradle files, which include build scripts, settings scripts, and init scripts. The build scripts are further divided into root/top level build scripts and module level build scripts. The context then explains the structure of gradle scripts, including the use of dependencies, version codes, and version names. Finally, the context discusses the difference between "api" and "implementation" in gradle scripts and recommends using "implementation" for better build time performance.

Opinions

The author of the context seems to have a positive opinion towards Gradle and Groovy, as they highlight the benefits of using them in software development. They also seem to have a preference for using "implementation" over "api" in gradle scripts, as they recommend using it for better build time performance. Additionally, the author encourages readers to try out an AI service that they recommend, suggesting that they have a positive opinion towards this service as well.

The simplest guide to understanding Gradle!

Gradle- how often do we neglect this amazing build system and treat it as a black box, blindly copy pasting code into it! While that, without a doubt, is so very convenient (hail Stack Overflow!) , it wouldn’t hurt to know what goes on behind the hood, now would it?!

In this article, we’ll be talking about

  • Types of Gradle scripts: build.gradle, settings.gradle and gradle.properties
  • Structure of gradle files
  • api vs implementation

So let’s get started…

Or wait..

Before we talk about the structure and types of Gradle files, let’s first touch base with the language it uses. Nothing fancy, I promise, but totally worth your time!

ENTER GROOVY!

Gradle build scripts are written in Groovy: a JVM language similar to Java but with a more concise syntax.

Here is all you need to know about Groovy to understand what’s going on:

  1. Valid Java is Valid groovy.
  2. We don’t need a surrounding class and main method to execute our code. Also, Groovy automatically imports System.out; so we can omit that wherever required.
  3. Semicolons are optional.
  4. There’s no need for parentheses when calling methods with at least one parameter (Java Closures).

Which is to say that we can reduce

System.out.println(“Hi, there!”);

to

println “Hi, there!”

Let’s understand it better with an example

In groovy console, we define a class like

class MyClass{
}

Let’s add a method that takes a Closure:

class MyClass{
    doSomething(Closure closure)
     {
        closure.call()
     }
}

To run whatever code is in the closure with closure.call() we’l l create an instance of MyClass and call doSomething like:

MyClass myClass = new MyClass();
myClass.doSomething{
   println “Hi, there!”
}

Which outputs the following

Hi, there!

Does the following look familiar now?

dependencies{
    testCompile group: ‘junit’, name: ‘junit’, version: ‘4.22
}

Dependencies is a method which takes a “runnable” block of code (a closure). Inside that block we’ve called the the testCompile method with group: ‘junit’ etc as an argument (the group, name, version section is actually short hand for a groovy map, essentially a list of key value pairs).

You can check the reference articles here and here.

I know, right! Such a revelation it is! The code you demonised in your head turned out to be only a couple of harmless function calls!

With this understanding of Groovy in mind, let’s now read about the types and structure of Gradle files, and decipher what means what.

Types Of Gradle Files

There are three main script files that Gradle uses.

  • build scripts in build.gradle files.
  • settings scripts in settings.gradle
  • init scripts used for global configuration

1. Build Scripts

There are 2 types of build scripts

- Root/top level gradle:

It is located in the root project directory and its main function is to define the build configurations that will be applied to all the modules in the project.

It is implemented as

buildscript
        {
            repositories
                    {
                        google()
                        jcenter()
                    }
            dependencies
                    {
                        classpath    'com.android.tools.build:gradle:3.0.1'
                    }
        }
allprojects
        {
            repositories
                    {
                        google()
                        jcenter()
                    }
        }
task clean(type: Delete)
{
    delete rootProject.buildDir
}

The top-level build.gradle supports various build configurations such as

  • buildscript: This block is used to configure the repositories and dependencies for Gradle.

Don’t include dependencies here. Those will be included in the module-level build.gradle

  • dependencies: This block in buildscript is used to configure dependencies that the Gradle needs to build during the project.

classpath 'com.android.tools.build:gradle:3.0.1'

This line adds the plugins as a classpath dependency for gradle 3.0.1.

  • allprojects: This is the block where one can configure the third-party plugins or libraries. For freshly created projects android studio includes JCenter and Google’s maven repository by default.
  • task clean(type:Delete): This block is used to delete the directory everytime the project is run. This way the projects keep clean when someone modify some config files like, during settings.gradle which require a complete clean.

- Module level build.gradle

Located in the project/module directory of the project, this Gradle script is where all the dependencies are defined and where the sdk versions are declared. This script has many functions in the project which include additional build types and override settings in the main/app manifest or top-level build.gradle file. It is implemented as:

// The first line in this file indicates
// the Android plugin that is applied for Gradle to
// this build
apply plugin : 'com.android.application'
android
        {
            compileSdkVersion 26
            defaultConfig
                    {
                        applicationId "example.abc.xyz"
                        minSdkVersion 19
                        targetSdkVersion 26
                        versionCode 1
                        versionName "1.0"
                    }
            buildTypes
                    {
                        release {
                             minifyEnabled false
                                  
                                }
                         debug {
                            ext.alwaysUpdateBuildId = false
                            multiDexEnabled true
                            ext.enableStability = false
                        }
                    }
}
dependencies
                    {
                        api 'androidx.appcompat:appcompat:1.0.2'
                        implementation 'com.abc.xyz'
                 }

The Module-level build.gradle supports various build configurations like:

  • android: This block is used for configuring the specific android build options eg the compileSDKversion.
  • defaultConfig:

— applicationId: This is used for identifying unique id for publishing of the app.

— minSdkVersion: This defines the minimum API level required to run the application.

— targetSdkVersion: This defines the API level used to test the app.

— versionCode: This defines the version code of the app. Everytime an update needs to be of the app, the version code needs to be increased by 1 or more.

— versionName: This defines the version name for the app. this could be increased by any much while creating an update.

  • buildTypes(release/debug):

— minifyEnabled: this will enable code shrinking for release build.

— proguardFiles: this will specify the Proguard settings file.

  • dependencies: This specifies the dependencies that are needed to build the project.

2. Settings.gradle

The settings.gradle file is a Groovy script, just like the build.gradle file. Only one settings.gradle script will be executed in each build (in comparison to multiple build.gradle scripts in multi-project builds). The settings.gradle script will be executed before any build.gradle script and even before the Project instances are created. With this, you can add sub-projects to your build, modify the parameters from the command line (StartParameter), and access the Gradle object to register lifecycle handlers. As a consequence, use settings.gradle if your settings are build-related and not necessarily project-related or require logic before possible subprojects are included.

It looks something like

include ':clevertap-android-sdk-1.2.4'
include ':app', ':accountkitsdk', ':PhoneVerificationLibrary'
include ':library'

project(':base').projectDir = new File('BaseModule/base')
project(':PhoneVerificationLibrary').projectDir = new File('BaseModule/PhoneVerificationLibrary')
project(':library').projectDir = new File('BaseModule/library')

3. Init Script (gradle.properties)

The gradle.properties file is a simple Java Properties file that only gains a special role by being automatically included into the scope of the Project object. It's a simple key-value store that only allows string values (so you need to split lists or arrays by yourself). You can put gradle.properties files to these locations:

  • directly in the project directory (for project-related values)
  • in the user home .gradle directory (for user- or environment-related values)

It typically looks something like:

org.gradle.daemon=true
org.gradle.parallel=true
android.injected.testOnly=false
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
org.gradle.configureondemand=false
systemProp.apollographql.useGlobalApolloCodegen=true

Phew! That was long but don’t you feel a tad enlightened? Just a few final, parting words:

You must have come across words like “api/implementation” in your build.gradle files. If you’ve ever wondered what these imply and where to use which one, read on!

“api” vs “implementation”:

You can compile a dependency by using either “api”(previously called ‘compile’) or “implementation”. The difference is that when a dependency is compiled using api, the whole project tree gets the access to the dependency and so if any change is implemented inside the dependency, the whole tree is recompiled, while as in case of implementation, only the immediate module (the one in which the dependency is defined) has access to the dependency and so any change to the dependency recompiles the immediate parent only.

Which one to use?

It’s always better and recommended to use ‘implementation’ as it saves you a lot of build time. Just replace all api with the implementation and try to build the project. If it builds successfully, well and good; otherwise look for any leaking dependency you might be using and import those libraries using api keyword.

Read this awesome article for more clarity on the topic!

That’s it for now, folks! Adios!

If you would like to send a little encouragement my way, here is the link for that :)

Android
Android App Development
Gradle
AndroidDev
Android Apps
Recommended from ReadMedium