Let’s see how we typically log something in Android using Java before Kotlin.
But this is not how we actually do it, right? We don’t want to leak the logs in release build. So we use a util class which actually calls the Log
methods, guarded by a BuildConfig.DEBUG
check.
As you can image, we would have other methods for Log.i
, Log.v
, Log.e
etc. This works pretty well, but can we do something better than this with the power of Kotlin?
First let’s see some problems with this typical approach.
- TAG variable needs to be in every class we wish to add log.
- The message is eagerly evaluated which is a problem if you do extensive logging, since on release builds even though the message is not used, it would still be evaluated.
Let’s see an upgraded version of this using Kotlin.
Ah! This is much better.
- We are adding the
log
method as an extension of typeAny
here.Any
is the equivalent ofObject
from Java and hence thelog
method is an extension of it, we can access this method using all instances of all objects. - We are also setting the class name as
TAG
. This removes the need to have a separate variable for this. - Now the interesting part is, we are not taking the message directly, but as a function which returns the message. This makes the message lazily evaluated and in release build, the lambda inside
log
method calls won’t ever be executed. - Another interesting part is, we made the
log
method as an inline function. It basically means, thelog
method body would be copy-pasted at the call site andlog
method and method call would not be present after compilation. So this eliminates the overhead of creating separate function (which is actually an instance of typeFunction
at bytecode) for eachlog
method call.
Again, we can have separate functions for all variants of Log like logD()
for Log.d
, logI()
for Log.i
etc.
Live Templates
One cool thing about the traditional Java logging is that Android Studio has some nice live templates to add logs.
It would be nice to have these kind of live templates to add our own log methods, right? Let’s do it.
If you go to File -> Settings/Preferences -> Editor -> Live Templates, under AndroidLog you can see the live templates shown in the above gif.
We can start adding by
- Clicking on the plus icon on top right
- Select Template Group
- Give a name, ex: AndroidLogKotlin
- Click the plus icon at top right again
- Select Live Template
- Now we can just copy paste Abbreviation, Description and Template text from logd from AndroidLog.
- Change the template text to use our logging method. We can just add like
log { “$METHOD_NAME$: $content$” }
and import the log method after usage or add with full package name to auto import on usagecom.example.app.extensions.log { “$METHOD_NAME$: $content$” }
- Select Reformat according to style option (this is optional)
- Now click Define at the bottom near the error No applicable contexts and select Kotlin -> Statement.
- Now repeat the steps from 4 to 9 for all other Log variants like
logI
,logV
,logE
etc.
This is how it looks like after adding these live templates.