The Medieval city of Kraków, Poland. Photo by Jacek Dyląg.

A short story about developing an SDK for Android. Part 3.

Paweł Dyląg
6 min readNov 19, 2017

This is the last part of the short series of articles, where I share a couple of tips that could help you improve your SDK/library development for Android.

This time we will talk about handling your builds, and distribution, which is the last step in the whole development process. You are sitting in a tavern, sipping a deep dark beer, where the bartender tells you the story about the city of Esdeekya.

Psst… click here for some pleasant music to make you feel like sitting in a tavern!

1. Make the most of your build.gradle file

“The constructors had clever overseers and managers. They kept their plans and schemes clear and coherent, so that the future developers would easily understand their designs. Oh, I got one set of documentation from a friendly engineer!” He pointed at the back of the tavern. “I hung it above the fireplace. I would dare say that it is a true piece of engineering art!”

Gradle is a fantastic tool that lets you build your project fast and easy. Going beyond simple usage may drive your project to the next level. I encourage you to take a deep dive into the docs — you will find lots of useful features there.

Versioning your code

One simple idea is to automate your version name/code generation. I found this solution somewhere on the internet and I think it is pretty straight-forward, so I want to share it with you:

You can use these functions in defaultConfig or in any place you need the generated version. What is cool is that you keep your version numbers in one place.

Consider using BuildConfig fields

There are many ways to parametrise your build, but you can easily do it using build.gradle config field declarations:

You can access these fields in your code like this:

val cloudEndpoint = BuildConfig.CLOUD_ENDPOINT

As I said, this is one of many possible ways. Take a look at this neat guide to find out more tips and tricks!

2. Use Bintray to distribute artifacts to JCenter

“Well, I must say that they quickly rebuilt houses, walls, towers, even the town hall. Where they were done with almost every building, the time has came to let the people in.” The bartender took his rag and started cleaning the previous glass. “God, those are never fully clean,” he mumbled.

The deployment process is one of the most important things. If it is fully automated, secure, and easy, it will boost your development, and will allow you to move forward very quickly. I came a long way to finally settle down on one particular mechanism. Let us start with the basics.

What is JCenter?

JCenter is the place to find and share popular Apache Maven packages for use by Maven, Gradle, Ivy, SBT, etc.

Short version — this is the main repository from where the Gradle build tool will try to download needed libraries. So in order to distribute our own library/SDK, we need to put our stuff there.

How to setup an external repository for a project?

In order to download the libraries it needs, Gradle build tool has to know in which external repository to look for them. This is simply defined in the build.gradle file. You can setup this for each of your modules separately (in the module’s build.gradle), or for the whole project in the main build.gradle:

allprojects {
repositories {
jcenter()
}
}

You can also add additional repositories, for example Maven Central:

allprojects {
repositories {
jcenter()
mavenCentral()
}
}

The priority is from top to bottom. In above example, the build tool will look for artifacts in JCenter, and then in Maven Central.

What is the difference between JCenter and Maven Central?

Maven Central is a subset of JCenter. In other words — what is available in Maven Central, will also be available in JCenter. Plus JCenter has much better UI, easier deployment process, and many more advantages.

What is Bintray?

Bintray is a deployment platform used to host and deploy repositories. It is maintained by JFrog, which is also responsible for JCenter, so the integration is, well, let us say ‘out of the box’. You can deploy your library to a private repository (paid version), or to a public one (free version).

How to deploy a project using Bintray?

It is rather simple — you can do it manually, or automate it with scripts. There are many scripts you can use within your Android Studio, but I encourage you to read this tutorial about Bintray upload script for Gradle. There is almost everything you need to do in order to automate your release process.

How to effectively debug a library without releasing it?

So let us say you want to distribute a library to your colleague. You also don’t want to release it publicly for now, because it is just a dev version.

One way to do it is to take compiled .aar file and to send it directly to your colleague (or to your another project locally — an app for example). This requires a lot of manual work — copying stuff, moving it around, and so on. It will definitely drive you insane after doing it numerous times, trust me.

There is a better way!

For releasing remotely — release your library to a private repository on Bintray using the release script. Then let your colleague setup an external repository like this:

allprojects {
repositories {
jcenter()
maven {
url "https://YOUR-PRIVATE_REPO_URL_HERE"
credentials {
username = "${YOUR_BINTRAY_USERNAME}"
password = "${YOUR_BINTRAY_PASSWORD}"
}
}
}
}

Your colleague would probably have to setup the credentials for accessing Bintray, but it is one-time only task. After that, your library will be accessible as usual via the compile'com.blah:blah:1.0.0'. Cool!

For releasing locally — when you want to use the compiled library on the same machine, but for example, in a different project, you need to install it in your local maven repository.

  1. First, deploy your library to the local Maven repository. Go to your project folder and run Gradle’s install task:
    UNIX/Mac:./gradlew install
    Windows: gradlew install
  2. Check if it appeared in your local Maven repository folder. Use the path:
    UNIX/Mac: ~/.m2
    Windows: C:\Documents and Settings\{user}\.m2
  3. In the project in which you want to use your deployed library, add mavenLocal() to your build.gradle file like this:
allprojects {
repositories {
mavenLocal()
jcenter()
}
}

Add your library as you usually do, using compile'com.blah:blah:1.0.0'
Boom! Hit the “Gradle Sync” button, and you should see the library compiled into your project. Neat!

Tip: Sometimes if you update your local repository with the library of the same version as the previous one, Gradle won’t use it, because the same version would have been cached by the Gradle earlier. This will cause it to use the previous classes, without your new changes. You can fix this by building your project with --refresh-dependencies (not the library project, but the module using it)

3. Be assertive.

“I guess this is it, my fellow listener. Now you know what happened to the city of Esdeekya, and why living here is so pleasurable.” The bartender took the empty mug from you. “Lesson to learn? Well, if you would ever attempt to build a city — but why would you — remember that it needs to last for centuries. Save your future time on spending more time doing proper design today. And, for goodness sake, learn to say ‘NO’ when you know something needs repair!” He reached his hand out, “Two dark beers… plus the story is on me. That’d be eight silver coins.” He smiled.

Summary

  1. Configure your build.gradle file to make the most out of your builds. Use custom functions to automate your version code generation, or parametrise your builds with BuildConfig fields.
  2. Consider using Bintray to release your builds to JCenter even faster! Configuring the release script will let you minimise the amount of work to just a single ./gradlew bintrayUpload.
  3. Release your builds to your local Maven repository using gradlew install task.
  4. Learn to say “no”. At the end of the day, you are the one responsible for any failures. It is better to do quality, long-lasting things slowly, than poor, short-lived things fast.

I had lots of fun writing all three parts of the story — I hope you also enjoyed reading it!

If you have got any comments, feedback, or questions — feel free to ask me! You can reach me via my email: pawel@paweldylag.com,
follow me on
Twitter, Github or LinkedIn,
or just ask questions directly in the comments :)

--

--

Paweł Dyląg

Android Software Engineer, ex @Estimote, tech geek, music addict, science enthusiast, RPG fan, book lover, and just a nice guy from Kraków, Poland.