1. 程式人生 > >Kotlin DSL to write Gradle scripts on Android: Step by step walkthrough

Kotlin DSL to write Gradle scripts on Android: Step by step walkthrough

There’s been quite some months already since Gradle announced that they were working on supporting Kotlin to write Gradle Scripts, by using a version of the language that has been recently revamped to Kotlin DSL.

At the beginning things where quite complicated, but nowadays, with latest versions of Kotlin DSL (at the time of writing this the version is

0.12) the idea is more mature.

So, knowing how, it’s not too difficult to start using Kotlin to build your Gradle files in Android.

One of the main issues of this is the lack of documentation, so I decided to write about my experience converting the Gradle files of Bandhook-Kotlin, so that you can replicate it in your project.

If you’re still starting with Kotlin, you may be interested in checking out my previous articles about Kotlin.

Using Kotlin DSL on your Gradle files. Is it worth it?

I guess this is the first question to solve. As of today, should I spend my time converting my files to Kotlin DSL?

My answer is probably a bit counterproductive to encourage you continue reading this article, but I don’t want you to be hyped because of this: you probably shouldn’t

.

It has of course some pros:

Want to learn Kotlin?

Check my free guide to create your first project in 15 minutes!

  • You can used a language you’re more familiarized with, so it’s easier to start doing more complicated things. I had never done anything on buildSrc folder, and it was quite easy for me to create my own class and use it in the rest of the script files.
  • The IDE helps you a lot more: nice autocomplete, the errors are detected by the compiler, imports added automatically… All you know and love from your regular Kotlin code is kind of extrapolated here.

But also has some cons:

  • There’s not a straightforward way to convert from Groovy to Kotlin files. I’ll explain you how to make it easier though
  • You need to know how the plugin is implemented to be able to use it: where in Groovy you just use an equals to assign a value to every configuration, here you need to know whether it’s a function or a property to know how to set it. Gladly the IDE can help. Gradle team says that this will only be solved when people write the plugins thinking also on Kotlin DSL. There are some rules to follow. An example (we’ll see more later):
12345 applicationId=Config.Android.applicationIdminSdkVersion(Config.Android.minSdkVersion)targetSdkVersion(Config.Android.targetSdkVersion)versionCode=Config.Android.versionCodeversionName=Config.Android.versionName
  • There’s not much documentation or examples: I think this is the main problem. If you get stuck, it’s difficult to continue. It took me quite some time (and asking on the great Kotlin Slack) to know how to do some things.

So a big disclaimer here: be sure of what you’re doing if you use it in your production code. Can be a interesting thing to do in your pet projects though. I’m not saying it’s not mature enough, just that it’s not easy to use.

How to convert your files

I want to give you here the fastest route, by skipping all the pain points I had to solve. So if I had to convert another project to use Kotlin on Gradle files, that’s what I’d do.

Use the latest version of Gradle

The newer the Gradle version, the better, because it will include the latest Kotlin DSL version. When I converted this project, the latest one was 4.5.1. You can check the latest release here. Modify your gradle-wrapper.properties file to use it:

12345 distributionBase=GRADLE_USER_HOMEdistributionPath=wrapper/distszipStoreBase=GRADLE_USER_HOMEzipStorePath=wrapper/distsdistributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-all.zip

Change the name of your files

I must admit that, since first time I tried, things have improved a lot. Before, you had to add many configurations that you wouldn’t need when using Groovy.

Now, you just need to add an extension to your build.gradle files, and Gradle will be able to use Kotlin files. Rename them to build.gradle.kts.

Compile using the terminal

The IDE won’t help you much here in understanding what’s wrong, so I recommend you using cmd and the --info flag:

1 ./gradlew assembleDebug--info

With this, you’ll get a better idea of the things that are not working. You can do it now if you want, but it will obviously fail.

Configure your buildSrc folder

One of the pain points I found was a way to replicate the ext object in Groovy, that allows you to share variables between Groovy files:

12345 ext{// Android configandroidBuildToolsVersion="27.0.3"...}

You can have that in your root Gradle file, and then use it in your modules:

1 buildToolsVersion parent.ext.androidBuildToolsVersion

That’s pretty easy, and works fine. The alternative in Kotlin DSL is this: for each variable you need to create an extra like this:

12 varandroidBuildToolsVersion:Stringby extraandroidBuildToolsVersion="27.0.3"

And then you use it with this:

12 val androidBuildToolsVersion:Stringby extrabuildToolsVersion(androidBuildToolsVersion)

As you can imagine, this doesn’t scale up very well. Having all this code for each variable is a pain.

So the alternative I found is to create a configuration file in the buildSrc, and add all you need in an object that you can then instantiate in any Gradle files. If you don’t know about it, the buildSrc is basically a place where you put all the code that you want to use when building the project scripts. You can find more info in Gradle Docs.

To configure it, just create this folder structure under the buildSrc folder:

Forget about .gradle and build folders and create the rest.

Under that folder, also create a new build.gradle.kts with this content:

123 plugins{`kotlin-dsl`}

The Config file will be the one to hold the variables you may use in your project. You can use whatever structure you want. While looking for info on how to do this, I found the repository from Arturo Gutiérrez that uses this structure, and I liked it. I’ve moved to use objects instead of classes though, which makes more sense here:

123456 objectConfig{objectBuildPluginsobjectAndroidobjectLibsobjectTestLibs}

Then, each child object has its own values. For instance, the Android one:

123456789 objectAndroid{val buildToolsVersion="27.0.3"val minSdkVersion=19val targetSdkVersion=27val compileSdkVersion=27val applicationId="com.antonioleiva.bandhookkotlin"val versionCode=1val versionName="0.1"}

You can also use some top variables to make it easier to edit:

12345678910 privateconstval supportVersion="27.0.2"...objectLibs{val appcompat="com.android.support:appcompat-v7:$supportVersion"val recyclerview="com.android.support:recyclerview-v7:$supportVersion"val cardview="com.android.support:cardview-v7:$supportVersion"val palette="com.android.support:palette-v7:$supportVersion"val design="com.android.support:design:$supportVersion"...}

Then, using it in your build.gradle files is pretty straightforward:

123456789 defaultConfig{applicationId=Config.Android.applicationIdminSdkVersion(Config.Android.minSdkVersion)targetSdkVersion(Config.Android.targetSdkVersion)versionCode=Config.Android.versionCodeversionName=Config.Android.versionNametestInstrumentationRunner="android.support.test.runner.AndroidJUnitRunner"}

As you see, it looks much cleaner.

Keep converting your Gradle files

Until the first time it completely compiles, you’ll have to rely on what the terminal builds say, the IDE won’t be very useful here.

So continue changing parts little by little, building the project, and interpreting the output. As a reference, I can leave you some parts of the Gradle files here (and you can, of course, check the complete project on Github).

For the root build.gradle:

1234567891011121314151617 buildscript{repositories{jcenter()google()}dependencies{classpath(Config.BuildPlugins.androidGradle)classpath(Config.BuildPlugins.kotlinGradlePlugin)}}allprojects{repositories{jcenter()google()}}

This one becomes quite simple, as we’ve extracted all kinds of configuration to the Config.kt file.

The module file is a bit more complicated. For the plugins, you do it like this:

12345 plugins{id("com.android.application")kotlin("android")kotlin("kapt")}

For regular plugins, you just use the function id, and Kotlin plugins use the function kotlin.

Then the Android section is like you saw above. You need to try in order to discover whether it’s a function or a property. Check the repository the most typical ones. Then, for the build types:

123456 buildTypes{getByName("release"){isMinifyEnabled=falseproguardFiles("proguard-rules.pro")}}

You can’t just create a release block, but instead it’s required to find it by name, and then you can configure it.

The dependencies are easy, just functions where you set the name of the dependency:

1234 dependencies{compile(Config.Libs.kotlin_std)...}

Keep building and polishing until the build succeeds.

It’s not easy, but it’s cool!

It’s really awesome to see how Kotlin is reaching to all development environments: JVM, JS, Gradle… and potentially everywhere with Kotlin/Native.

This is just another example of the versatility of the language, and gives an idea of how enthusiastic the different developers communities are becoming about it.

In the case of Gradle, maybe it’s not yet production ready (though I know of people that are using it without many issues), but it’s worth giving it a try and check how nice it works once everything is configured.

Having compile time errors and autocomplete is of great help when we’re building our Gradle files, which otherwise requires just hard memory or searching.

What do you think about Kotlin DSL? Have you tried? Are you using it in your projects? Let me know in the comments.

I’m in love with Kotlin. I’ve been learning about it for a couple of years, applying it to Android and digesting all this knowledge so that you can learn it with no effort.

Shares

Like this:

Like Loading...

相關推薦

Kotlin DSL to write Gradle scripts on Android: Step by step walkthrough

There’s been quite some months already since Gradle announced that they were working on supporting Kotlin to write Gradle Scripts, by using a version

How to make unit test on Android with Kotlin (KAD 22)

Of course, Kotlin also allows us to do unit tests in a very simple way, and very similar to what we’re used in Java. There are some small complicatio

How to use Dagger 2 on Android with Kotlin (KAD 20)

Virtually everyone who wants to create code on Android in a decoupled and easy-to-test way, resorts to Dagger sooner or later. Although there is some

gradle kotlin Unable to get Gradle home directory

建立了一個gradle的kotlin版本,然後一直 在環境變數中加入GRADLE_HOME就好了 看一下kts指令碼內容 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("j

How to install Google Play Services on Genymotion Step by Step

Due to Genymotion's fluidness and ease of use, it now becomes the most popular android emulator allows android developers to test their a

Illustrated Guide to LSTM's and GRU's: A step by step explanation

Then I'll explain the internal mechanisms that allow LSTM's and GRU's to perform so well. If you want to understand what's happening under the hood for the

Build Hadoop 2.7 from source on Centos step by step

Hadoop is one of the best open source for store and processing big data. It has a lot of supports from community and many big companies have used it fo

debug python step by step on linux ubuntu with ipdb

在Linux下單步除錯python一直是一件憂傷的事情,進來研究別人家的python原始碼,沒debug方法真是看的累,試用了下ipdb,感覺還可以,有點gdb的感覺。     1>.安裝 pip install ipdb 或: easy_install ipdb  

資料庫設計Step by Step (9)——ER-to-SQL轉化

參考連結:http://www.cnblogs.com/DBFocus/archive/2011/07/25/2116609.html     引言:前文(資料庫設計 Step by Step (8)——檢視整合)討論瞭如何把區域性ER圖整合為全域性ER圖。有了全域性

if you want to fly,you need to walk step by step

http://blog.csdn.net/panxueji/article/details/9949841 來源(來源不明-轉載請標明此連結)一、IO流的三種分類方式:1.按照流向來分:輸入流:只能從中讀取位元組資料,不能向其寫出資料輸出流:只能向其寫入位元組資料,不能從中讀

[Transducer] Step by Step to build a simple transducer

times function lec const gate reduce uil ould lose Transducers are composable algorithmic transformations. They are independent from th

How to use Retrofit on android with Kotlin (KAD 21)

This is just one more example about how in Kotlin we can continue to use the same libraries we’ve always used in Java for Android. Retrofit is a libr

Android Gradle指令碼從Groovy遷移到Kotlin DSL

Android Gradle從Groovy遷移到Kotlin Android專案用Gradle構建, 其指令碼語言之前是Groovy, 目前也提供了Kotlin的支援, 所以可以遷移到Kotlin. 官方的遷移文件: Migrating build logic from Groovy to Kotlin 說明

Android Error:Failed to complete Gradle execution. Cause: The version of Gradle you are using (3.3)

Android 打包錯誤: Error:Failed to complete Gradle execution. Cause: The version of Gradle you are using (3.3) does not support the forTasks() me

Gradle學習之Android-DSL AppExtension篇

前言:上一篇文章已經講解了Gradle的語法篇,接下來我們要開始學習android-gradle-dsl了,不過我上一篇漏寫了一節函式,這個我打算接下來補上,俗話說的好墨刀不誤砍柴工,上一篇文章我們的刀已經磨好了,下面我們開始收穫我們的成果了,或者說該應用實戰

@BindView問題 Attempt to invoke virtual method 'void android ...' on a null object reference

Caused by:java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.Toolbar.setNavigationIcon(int)

Just tell Google Assistant to play Netflix on Android TVs

Until now, casting video to an Android TV through a Google Assistant-enabled device such as a Google Home or the new JBL soundbar has been a fairly simple

First Look at New Android Gradle Build Tools: The new DSL structure and Gradle 2.5

Android Studio 1.3's stage is closed to the stable release. New features are keep coming including full NDK support. And it seems like so

How to debug HTTP(s) traffic on Android

You can create as many proxy configurations as you want. When you want to enable one, simply tap on the currently connected network, enable the proxy and s

[PWA] Add Push Notifications to a PWA with React in Chrome and on Android

On Android and in Chrome (but not on iOS), it's possible to send push notifications with a PWA. We'll start by asking the user for permission to send them