Creating a custom gradle plugin for android
Using gradle plugins in your build scripts can provide alot of powerful benefits, this is a high level tutorial on how to build a custom plugin you can re-use over multiple projects.
Custom gradle plugin for Android
For more information on almost any step, please see afterecho’s fantastic blog post (linked in the Additional Resources section).
Prep and tools
You will need the following installed.
- Intellij IDEA the free community edition will be more then enough.
- Groovy this should be installed when Android studio was installed.
- Gradle this should be installed when Android studio was installed.
Project setup
- In intellij create a new gradle project, select the options to add additional libraries for java and groovy. You’ll need to provide the following details:
GroupIDthis is how your plugins will be grouped, its a good idea to stick to your java package convention of the reversal of your domain name.ArtifactIDthe name of your pluginVersionthis should be pre-populated as1.0-SNAPSHOT, you can leave that as is. TheSNAPSHOTkeyword will mean that everytime time your compile your archives a new version will be made that is time and date stamped, if you remove that and make your build version1.0, the archives will be overidden every time.
- Now that we have the project setup, check if a
srcdirectory was created, if it was you can skip the next point and procede to making your packages.- Create a new directory with the following
src/main/groovy, thegroovydirectory should be highlighted a different colour to indicate its a source directory. - Inside the
groovydirectory create your required packages.
- Create a new directory with the following
- We will need to add the following 2
dependenciesin thebuild.gradlefile that was generated.compile gradleApi() compile localGroovy()
Creating the plugin
To create the plugin we are going to need three things, the task classes that will be included, the plugin class that will set them all up and the properties file that will tell gradle where to find out plugin.
Task class
Create a task that you want to be made available with the plugin, you can have as many as you want included with a plugin:
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.tasks.TaskAction
class ExampleTask extends DefaultTask{
/**
* We use this to add the task to the project, this doesn't have to be
* done here, I put it here so everything with the task is kept in
* the same place.
*
* @param project the project the task will be added to
*/
static void init(Project project){
// Create your task and give it a name //
project.getTasks().create("exampleTask", ExampleTask.class)
}
/**
* Standard constructor, we will use it to set some globals for the task.
*/
ExampleTask() {
// Set the group that your task will belong to, eg. upload, this will be seen //
// in your ide, in android studio and intellij this will show up in the //
// gradle window //
group = "example"
// A description to help everyone know what your task does //
description = "Example task to print to the console"
}
/**
* The function that runs when the task is called.
* <p>
* This can be called anything, what is important is the @TaskAction annotation
*
* @throws Exception
*/
@TaskAction
void example() throws Exception {
// Perform task actions, we will just print something to the console //
println("Running example task")
}
}
Plugin class
Create the main class for your plugin, this will be the class that is implemented when you plugin is applied:
import org.gradle.api.Plugin
import org.gradle.api.Project
import task.ExampleTask
class ExamplePlugin implements Plugin<Project> {
/**
* This is the function that is run when the plugin is applied,
* its the first thing that will run.
*
* @param project the project that the plugin is applied to
*/
@Override
void apply(Project project) {
println("Applying Plugin")
// Create all the tasks you want to be made available //
// with the plugin //
ExampleTask.init(project)
}
}
Properties File
The propertiese file will give your plugin a name that can be used with including it, aswell as tell gradle what class to find your plugin in, there are 3 simple steps to this:
-
Create the following directories
resources/META-INF/gradle-pluginsunder thesrc/maindirectory. Theresourcesdirectory might already exist from the project setup steps. -
Create a new
.propertiesfile in the directory you just created, the name of this file will be the name of the plugin when it is applied, for exampleio.smileyjoe.example.gradle.propertieswould mean that this plugin would be used by callingapply plugin: 'io.smileyjoe.gradle.example. -
This file contains a single line,
implementation-class=ExamplePlugin, whereimplementation-classis pointing to your plugin class.
Making a repository
This guide is just going to focus on making the repository locally inside the project, there are a couple of steps to this:
- Add the following to the top of your
build.gradle, this will allow us to run the taskuploadArchivesand have the archives added to therepodirectory in the root of our project.
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('repo'))
}
}
}
- Now that you have your compiled archives, its a good idea to add their path into your global
gradle.propertiesethis will help when you implement it into multiple projects, add the following to your global properties.
EXAMPLE_PLUGIN_PATH = "<path_to_repo_directory>"
Implementing the plugin
In your android application open the project level build.gradle and add the following.
- In the
repositoriessection in thebuildscriptsection add.
maven {
// we can use the global gradle variable we created above //
url uri(EXAMPLE_PLUGIN_PATH)
}
- In the
dependenciessection in thebuildscriptsection add the classpath, this uses theGroupID,ArtifactIDandVersionthat we used in the Project Setup
// <group_id>:<artifact_id>:<version> //
classpath 'io.smileyjoe.gradle.example:plugin:1.0'
The top of the file should look something like this now.
buildscript {
repositories {
jcenter()
maven {
url uri(EXAMPLE_PLUGIN_PATH)
}
}
dependencies {
classpath 'io.smileyjoe.gradle.example:plugin:1.0'
classpath 'com.android.tools.build:gradle:2.3.2'
}
}
Now open the module level build.gradle file and apply the plugin at the top:
apply plugin: 'io.smileyjoe.gradle.example'
Additional Resources
This guide is largely based on the following pages.
- afterecho has one of the best, if not the best, guides I could find on how to get this working.
- Andr? Diermann for help with having tasks as a seperate class.
- Stackoverflow because stackoverflow.