Whenever we want to try out a new library or just test out something specific in Android, we create a new Android project in Android Studio. While setting up a basic project is easy and simple these days, there are often plenty of boiler-plate required to get started. In this short post I'll introduce a code snippet I tend to re-write every time, but which I now made into a GitHub Gist that is easy to copy.

For small or temporary projects we can skip a lot of the setup and boiler-plate we otherwise need, but one thing that we almost always have to deal with is logcat. We want to be able to print log statements, but we probably also want to be able to easily run unit tests on the code we write. To fix that I tend to write small global wrapper functions around the functions in java.util.Log. I finally got tired of repeating that, so I made it into a GitHub Gist that I can easily reuse and share with others.

Usage

The utility is super simple to add your own project. Simply copy the code and paste it into a source directory in Android Studio.

To use the utility, just call one of the functions.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        logd("Hello, World!")
    }
}
Prints "Hello, World!" in Android logcat

The functions also supports an optional Throwable parameter, allowing you to print exceptions as we normally do with logcat.

fun testLogWithException() {
    try {
        functionThatThrows()
    } catch (e: Exception) {
        loge("Something went wrong!", e)
    }
}
Log printing with exception

But why?

If you're an experienced Android developer, you are probably aware of the excellent Timber library. Timber is far more advanced and flexible than this little code snippet, so why should you use it? In fact, I do recommend all apps to use Timber instead of writing their own wrapper for logcat or using this. It's powerful API allows you to avoid leaking log printouts in production app as well as passing critical log statements to your analytics or crash reporting tool. My little utility does none of that.

The only problem with Timber is that it requires a setup in your Application class (or somewhere else that is only called once) to be useful. While this is usually not a problem in most larger applications, the small and temporary apps we create to test new things doesn't always motivate all the extra work needed for this.

But why not just use the existing Log API in the Android framework? It works fine and it doesn't require any extra code in your application. However, you can't use the Log class in code that is unit tests, or it will throw a RuntimeException. To solve this, this utility will catch the relevant exception and call the Kotlin println() function instead. It even handles exceptions by calling printStackTrace() when running on host. That means that we not only avoid the RuntimeException in unit tests, we can display log printouts in tests as well.

fun logd(message: String, throwable: Throwable? = null) {
    try {
        Log.d(TAG, message, throwable)
    } catch (e: RuntimeException) {
        println(message)
        throwable?.printStackTrace()
    }
}
Wrapper for Log.d() that calls println() when not running on Android

This is where KittyLog comes in. A small piece of code that quickly solves to problems: running unit tests on Android code that contains log printout, and also printing these logs in the console when running the tests.

KittyLog

The full code for this utility can be found below. Note that this is a simple utility not intended for production use. However, you can start using this and once your application grows, and then refactor the wrappers to simply delegate to Timber instead.

Feel free to use this or give some feedback if there is something you believe could be improved.