Kotlin — Faster Lazy for Android

Kotlin has the concept of Delegated Properties which allows you to create common functionality and it can be re-used to do custom actions, for example you can create a Delegated Property to print some logs every time someone updates the value of a field, save a value to a database and return it from there, or lazy fields that are going to be computed when you use it for the first time.
This Lazy Delegated Property is already in the Kotlin library so you can use it like this:
val lazyString: String by lazy {
Log.d(TAG, "executed only first time")
"My Value"
}
The first time you access lazyString field it will execute this initialization block (so you will see the log in logcat) and return your desired value, there after it will return always “My Value”, the cached result of the initialization process:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, lazyString)
Log.d(TAG, lazyString)
...
}D/MainActivity: executed only first time
D/MainActivity: My Value
D/MainActivity: My Value
The lazy Delegated Property is just a function as you can see here:
public fun <T> lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy<T> =
when (mode) {
LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer)
LazyThreadSafetyMode.PUBLICATION -> SafePublicationLazyImpl(initializer)
LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer)
}
And here comes the interesting part, it has different implementations according to this mode parameter (LazyThreadSafetyMode) that indicates which thread safe mode has to use.
As default it will use SynchronizedLazyImpl (which correspond to LazyThreadSafetyMode.SYNCHRONIZED mode), so if you use it in this way you are going to be thread safe.
In case you are using this in the Main Thread and you are sure that it’s not going to be used in different threads, then you can avoid all of this overhead to make it Thread Safe and just use it like this:
val lazyString: String by lazy(LazyThreadSafetyMode.NONE) {
...
}
And that’s it! you are using a faster implementation of the Lazy Delegated Property.
If you want to make it simpler, you can create a new function to always use “LazyThreadSafetyMode.NONE” and use it like this:
fun <T> lazyAndroid(initializer: () -> T): Lazy<T> = lazy(LazyThreadSafetyMode.NONE, initializer)
// Example usage:
val lazyString: String by lazyAndroid {
...
}
If you have any question you can reach me through these social networks:
Twitter: https://twitter.com/juanchosaravia
LinkedIn: https://www.linkedin.com/in/juansaravia
If you want to learn more about Kotlin I invite you to see my other tutorial:
“Learn Kotlin while developing an Android App”
Thanks!