Versioning Android apps
If you need to improve the versioning scheme of your android app, then you are reading the right story. Let’s discover together some best practices and their advantages.
There is something in the software world called Semantic Versioning. It consists of a couple of conventions to assign version numbers to your software. You can (or maybe should) read all the details here.
Basically, the idea is the following:
Given a version number MAJOR.MINOR.PATCH, increment the:
MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
As you can see, according to the previous definition, the MAJOR version on an android app doesn't make sense unless you have any kind of API to be consumed by other clients. If that’s the case, then you can use the pure Semantic Versioning definition. If not, you need to define when you should increment the MAJOR version.
One option could be to increment the MAJOR when the app has a big new feature, redesign or goal completed. Another approach is to increment the MAJOR after the MINOR version achieved the number 9. For example, you could have the versions 1.0.0, 1.1.0, … 1.9.0 and then 2.0.0. It’s just a convention to decide when to increment the MAJOR.
In my case, I use the second approach, but you can use any, as long as it is well defined and known by all the stakeholders of your app.
Another concept defined by the Semantic Versioning is the pre-release version. A pre-release version may be denoted by appending a version classifier that starts with a “-”. For example “3.1.0-beta”, “1.2.0-rc”, “4.1.3-preview”, “2.3.0-alpha”, “1.3.2-SNAPSHOT”.
You can use these version classifiers to quickly identify the kind of version of your app and avoid confusion between a pre-release and a release version. For example, in my case I use “-SNAPSHOT” during the development phase and remove that classifier before releasing the APK.
If you use the Google Play Alpha/Beta Testing program takes into account that it’s not a good idea to upload an APK with a version name ending in “alpha” or “beta”. The reason is that when you promote an APK to production, you are not able to change the version name, so your users are going to believe they have installed a non-stable version.
Version code & version name
As you may know, on android you have to define two version fields for an app: the version code (android:versionCode) and the version name (android:versionName). The version code is an incremental integer value that represents the version of the application code. The version name is a string value that represents the “friendly” version name displayed to the users. You can get more details here.
It’s a good practice to have a direct relationship between both versions to avoid confusion during the development and release process. At least, you should be able to infer the version name given a version code.
As described here, the official documentation proposes using a version code scheme that associates the version code and name, and also supports the upload of multiple APKs to Google Play. Take into account that the greatest value Google Play allows for versionCode is 2100000000.
I suggest using an adaptation of that scheme to also support the Semantic Versioning (assuming you will need two digits for the MAJOR, two for the MINOR and two more for the PATCH version).
My suggestion is to use a version code with 9 digits: integers that represent the supported configurations are in the higher order bits, and the version name is in the lower order bits. The first two digits represent the minimum API level for your APK. The next digit is for either screen sizes or GL texture formats (assign zero if you don’t need to use this). Then there are two digits for the major version, two for the minor and the last two for the patch version.
For example, when the application version name is 3.1.0, the version code for a minimum API level 4 APK would be something like 040030100. The first two digits are reserved for the minimum API Level (4 in this case), the third digit is for either screen sizes or GL texture formats (not used in this example, so a 0 is assigned), and the last six digits are for the application’s version name (3.1.0).
As you can see, you can go from version 0.0.1 to 99.99.99. So, you have room for more than 192 years of versions, releasing weekly and without taking into account the hotfixes !!!
Automate the versioning scheme with Gradle
If you use Gradle to build your app (and I hope you are using it) you can automate the versioning scheme including the following code on your build.gradle
You only have to configure the versionMajor, versionMinor, versionPatch, versionClassifier, isSnapshot and minimumSdkVersion to automatically generate the versionCode and versionName values.
To sum up, here are my main four suggestions
- Use semantic versioning or an adaptation of it, according to your needs.
- Use a versioning scheme that relates the version code with the version name. You should be able to infer the version name given a version code.
- Use a versioning scheme that supports multiple APKs uploads to Google Play. Maybe you don’t need multiple APKs now, but you could need it in the future.
- Use Gradle to automatically generate the version code and the version name of your app.
Try to follow these suggestions since day zero of your app to avoid some possible headaches in the future.
You can follow our
DipienMedium Publication for more productivity tools & ideas for Android, Kotlin & Gradle developers.
If you enjoyed this article, you might get value out of these as well!
Say bye-bye to Android Jetifier
6 steps to stop using Jetifier and increase your build speed
Stop generating the BuildConfig on your Android modules
Why generating the BuildConfig class is a bad idea