Boilerplate libraries: Simple Changelog

  • by

If you’ve been building Android apps for a while you’ll know that most apps have a number of things in common that you end up writing over & over again, and I’m not talking about findViewById.. (if you’re still doing this, ahem… Butterknife)

No I’m talking about things like a Rating Manager – to selectively prompt the user to rate the app (I’ll be sharing my library for this once I’ve cleaned it up 😅), or something as simple as a ChangeLog.

All of my apps present the user with a change log when they install the latest update letting them know what’s changed. I find it’s a great way to keep the user up to date, bring new features to the users attention & also a nice little nod to users who’ve reported specific issues which they can now explicitly see have been fixed in that release.

When you’re implementing something like a change log there’s a couple of scenarios to keep in mind:

  • If it’s a new install I don’t want the change log for this build to popup when they first open the app
  • If it’s an update over a previous build then I do want the change log to popup when they first open the app, so they can see what’s changed
  • If the user’s already been shown the change log for their installed build, I don’t want it to keep popping up every time they open the app
  • If the user wants to manually see the change log they need some way to do this

After writing the same change log code and logic over & over again for multiple apps, I fiiiinally got around to packaging it into a library which I now use across all my apps. Essentially I’ve boiled down my change log code in each of my apps to the following few lines..

First, build a change log object which can be done simply using a Changelog.Builder, a basic example looks something like this:

ChangelogBuilder builder = new ChangelogBuilder()
   //The version code this changelog applies to
  .setVersionCode({versionCode}) 
   //I user my version name i.e 1.3-beta etc..
  .setTitle({title});

You can then add lines to your change log using:

builder.addLineItem({someString});

When my app starts I then call this method from the Main activity (passing in the change log object we’ve just created):

ChangelogUtil.showChangelogIfRequired({someContext}, changelogBuilder.build(), {themeResId});

It handles all the logic internally so…

  • If it’s not a new install & the changelog for this release hasn’t been previously shown — it’ll display it to the user
  • If it’s been previously shown for the version code you supplied or it’s a new install — not an update, it won’t do anything

Also it might be good to note — you don’t need to specify a theme but, as some of my apps have the option to have a dark theme, for consistency I pass in a theme for those apps depending on if the user has enabled the dark theme or not.

Finally I call ChangelogUtil.showChangelog with the same params as showChangelogIfRequired to manually show the change log when needed, this is usually a button somewhere in my app for the user to manually be able to view the change log.

And that’s it — all the logic is handled in the library & it neatly displays your change log as a bulleted list (internally it’s using a recyclerview to do this for view reuse & efficiency).

You can find the library on GitHub here and you can add it to your project from Gradle via the JitPack repository (instructions on Jitpack if you don’t know how).

Feel free to use it, pick it apart, improve upon it.. And let me know what you think in the comments 🙂

A few things to note:

  • As it uses CharSequence for each line item you can pass in the text as bold or italic using html, various spanned styles, you name it.
  • You can add line items that will only show on specific android versions using addMaxSdkVersionLineItem or addMinSdkVersionLineItem. This is pretty useful when you’ve changed something that’s only relevant for a specific SDK version ie showing Notification channel support has been added — only applies to Oreo users.

Leave a Reply

Your email address will not be published. Required fields are marked *