Versioning Android apps

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 good practices and their advantages.

Semantic Versioning

There is something in the software world called Semantic Versioning. It consists on 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 client. 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.

Pre-releases

Another concept defined by the Semantic Versioning is the pre-releaseversion. 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 confusions 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 take 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 confusions 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 represents the supported configurations are in the higher order bits, and the version name is in the lower order bits. The first two digits represents 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).

Version code for 3.1.0 version name and minimum api level 4

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 hot fixes !!!

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

apply plugin: 'com.android.application'

ext.versionMajor = 1
ext.versionMinor = 2
ext.versionPatch = 3
ext.versionClassifier = null
ext.isSnapshot = true
ext.minimumSdkVersion = 19

android {
	compileSdkVersion 27
	buildToolsVersion "27.0.0"

	defaultConfig {
		applicationId "com.sample"
		targetSdkVersion 27
		minSdkVersion project.ext.minimumSdkVersion
		versionCode generateVersionCode() // 190010203
		versionName generateVersionName() // 1.2.3-SNAPSHOT
	}
}

private Integer generateVersionCode() {
	return ext.minimumSdkVersion * 10000000 + ext.versionMajor * 10000 + ext.versionMinor * 100 + ext.versionPatch
}

private String generateVersionName() {
	String versionName = "${ext.versionMajor}.${ext.versionMinor}.${ext.versionPatch}"
	if (ext.versionClassifier == null && ext.isSnapshot) {
		ext.versionClassifier = "SNAPSHOT"
	}

	if (ext.versionClassifier != null) {
		versionName += "-" + ext.versionClassifier
	}
	return versionName;

You only have to configure the versionMajorversionMinorversionPatchversionClassifier, isSnapshot and minimumSdkVersion to automatically generate the versionCode and versionName values.

Conclusion

To sum app, 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 upload 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 you some possible headaches in the future.

Leave a Reply