Creating custom Gradle plugins can aid in modularizing and simplifying build.gradle files for Android applications. This is particularly beneficial for multi-module Android app architectures.
A Gradle plugin is a reusable container of build logic that can be used across multiple modules and projects in the context of Android development. This makes it possible to create plugins tailored to specific needs, such as managing dependencies, automating tasks, or implementing code quality checks. As you’ll see shortly, these items are just a short summary of the numerous benefits of utilizing custom Gradle plugins.
Below is a list of potential advantages Android developers may enjoy, depending on your use case.
First, create a buildSrc module if you don’t already have one, and then create a new Kotlin class file named DemoPlugin. Add the following lines of code to the file.
import com.android.build.gradle.AppExtension
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.LibraryExtension
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
class DemoPlugin : Plugin override fun apply(project: Project) project.plugins.apply("kotlin-android")
project.plugins.apply("kotlin-kapt")
val androidExtension = project.extensions.getByName("android")
if (androidExtension is BaseExtension) androidExtension.apply compileSdkVersion(33)
defaultConfig targetSdk = 33
minSdk = 21
versionCode = 1
versionName = "0.0.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
>
val proguardFile = "proguard-rules.pro"
when (this) is LibraryExtension -> defaultConfig consumerProguardFiles(proguardFile)
>
is AppExtension -> buildTypes getByName("release") isMinifyEnabled = true
isShrinkResources = true
debuggable(false)
proguardFile(proguardFile)
>
getByName("debug") isMinifyEnabled = false
isShrinkResources = false
debuggable(true)
proguardFile(proguardFile)
>
>
>
composeOptions.kotlinCompilerExtensionVersion = Versions.KOTLIN_COMPILER_EXTENSION
compileOptions sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
>
project.tasks.withType(KotlinCompile::class.java).configureEach kotlinOptions jvmTarget = Versions.JVM_TARGET
>
>
>
>
>
>
After reviewing the DemoPlugin class, it becomes clear that it serves as a configuration container for a module-level build.gradle file. Inheriting from the Gradle Plugin class allows you to create a custom plugin. The class applies the kotlin-android and kotlin-kapt plugins, while also setting the targetSdk, minSdk, versionCode, and versionName properties. Additionally, buildTypes can also be configured to enable features such as obfuscation, resource shrinking, and proguard rules for specific builds.
To continue, navigate to the root-level build.gradle.kts file in the buildSrc module and add the following lines of code. If you do not have a build.gradle.kts file, you can create one. We’ll take a closer look at these lines shortly to understand their role in the configuration of the custom Gradle plugin.
plugins `java-gradle-plugin`
`kotlin-dsl`
>
gradlePlugin plugins register("demo-plugin") implementationClass = ".plugins.DemoPlugin"
>
>
>
repositories google()
mavenCentral()
>
dependencies implementation("com.android.tools.build:gradle:7.3.1")
implementation(kotlin("gradle-plugin", "1.8.10"))
implementation(kotlin("android-extensions"))
implementation(kotlin("script-runtime"))
>
Let’s breakdown what the build.gradle.kts contains.
To create our custom Gradle plugin, we first need to apply two plugins: java-gradle-plugin and kotlin-dsl. The java-gradle-plugin automatically applies the Java Library (java-library) plugin, adds the gradleApi() dependency to the API configuration, and validates the plugin metadata during the jar task. This makes it easier to develop Gradle plugins. The kotlin-dsl plugin, on the other hand, enables us to create Kotlin-based domain-specific languages (DSLs).
After applying the plugins, we need to register our custom plugin with Gradle so that it can be used and Gradle is aware of the implementing class. We do this in the gradlePlugin block.
Finally, we add the required dependencies for our custom plugin in the dependencies block. In this example, we include the Gradle build tools, gradle-plugin, android-extensions, and script-runtime libraries. However, the plugins and dependencies may vary depending on the requirements of your custom plugin.
Finally, open the app level build.gradle file and apply the demo-plugin in the plugins block of the file.
plugins id "demo-plugin"
.
>
android namespace ''
defaultConfig applicationId ""
>
>
dependencies .
>
With your custom Gradle plugin applied, the targetSdk, minSdk, versionCode, and versionName properties are automatically applied as part of the plugin. This means that you no longer have to specify these properties explicitly in the module-level build.gradle file for every module of your Android app. This not only saves time for developers but also promotes modularity and reusability of module-level build.gradle file properties in a multi-module architecture.
As an Android developer, I have had a great experience using custom Gradle plugins to handle module-level build.gradle file configurations. With the use of custom Gradle plugins, I no longer have to manually configure the same properties for each module of my Android app, such as targetSdk, minSdk, versionCode, versionName, and whatever other dependencies my modules may require. Instead, I simply apply my custom plugin and allow it to manage the module-level build.gradle file configuration. This not only saves me time, but it also keeps the properties modular and reusable across multiple modules. Using custom Gradle plugins has streamlined my development process and made my life as an Android developer much easier when working in multi-module architectures.
Custom Gradle plugins are an excellent tool for modularizing build configurations, properties, and dependencies for modules in Android apps. By leveraging the modularity and reusability of custom Gradle plugins, developers can streamline the development of multi-module apps and accelerate the development process by reusing build configuration. By thoughtfully designing tools and reusable components such as custom Gradle plugins ahead of time, Android developers can save themselves significant time and effort in the development process.