The Complete Magazine on Open Source

Gradle: Making Software Development Easier

7.28K 3

Gradle is a build tool, which accelerates productivity. As the blurb on its website says,”From mobile apps to micro services, from small startups to big enterprises, Gradle helps teams build, automate and deliver better software, faster”.

Gradle is an open source build system which is familiar to most Android developers. It uses a DSL (Domain Specific Language) built on the Groovy language for configurations, while Direct Acyclic Graph is used to determine the order of its tasks. This article explores Gradle’s features that make software development on Android easier.

Separating logic and resources for flavours or build variants
When developing projects, you may want to develop a mock project that uses sample data or a library like Stetho for network inspection. Consider an example where Application class initialises the needed libraries. Here, we can create a class named AppController, which has a method attach (context) (refer to Figure 1).

// check the file path in comments
// app/src/debug/java/com/example/appname/AppController.java
import android.app.Application;
import com.facebook.stetho.Stetho;

public class AppController {

public static void attach(Application application) {
Stetho.initializeWithDefaults(application);
}
}

// app/src/release/java/packagename/AppController.java

public class AppController {

public static void attach(Application application) {
// analytics sdk
}
}

Check the file path in the comments. On building the project, if it is a debug build, Cradle uses class files from the debug folder, by default, and from the main folder for common modules. In the application class (in the main folder), you can just use Appcontroller class methods.

// app/src/main/java/com/example/appname/App.java
import android.app.Application;
public class App extends Application {

@Override
public void onCreate() {
super.onCreate();
AppController.attach(this);
}
}

If you need flavour-specific class logic, create a folder named with that flavour name. You can also change the default path to flavour-specific code using the sourceSets method, but it is better to use the default option. You can use this flavour path to put specific configuration files like JSON files that you get for Google services.
You can conditionally include your dependencies also. In the example, Stetho dependency is only needed for your debug builds, for which you can use your build variant name with the compile method.

compile 'com.android.support:customtabs:25.2.0'
// only used on debug builds
debugCompile 'com.facebook.stetho:stetho:1.4.2'

Figure 1: Selecting build types or flavour

Creating flavour-specific resources or configuration values
In your app’s Gradle config file, you can also specify a flavour- or variant-specific resource value or config value. Check the code below:

android{

productFlavors {
mock {
resValue "string", "app_name", "Appname-Mock"
}

production {
resValue "string", "app_name", "Appname"
}
}

buildTypes {

debug{
buildConfigField "String", "RAMEN_EFFECT",”0”
}
release{
buildConfigField "String", "RAMEN_EFFECT", “1”
}
}
}

In the example, the resValue method creates a string resource with the key app_name and value based on the type of flavour. buildConfigField creates a field in the BuildConfig class, and you can access the generated values in your code using BuildConfig.FIELD_NAME.

Using the properties files for secret data
When you push your code to remote repositories, you may not want to share your API server details or API keys. For such cases, you can make use of the properties file and ignore this file in your version control (.gitignore file in Git).

// app/build.gradle
// tries to read from environment, useful for CI systems
def api_url = System.getenv("API_URL")

Properties properties = new Properties()
// lookups config.properties file in project root
if (project.rootProject.file('config.properties').exists()) {
properties.load(project.rootProject.file('config.properties').newDataInputStream())
api_url = properties.getProperty('apiUrl')
}

In the above example, the Gradle config will read the secrets from a properties file (config.properties) and assign it to a variable. This variable can be used with the resValue or the buildConfigField methods in the application code.