Lazy and map standard delegates and SharedPreferences custom delegate Using some features is easy to write clean and readable code. Thanks to data classes, properties, extension functions and delegates a Kotlin class is usually smaller and easier to read compared to the equivalent Java class. In this post we’ll see how to use Kotlin delegated properties to simplify code. If you are not familiar with this subject you can take a look at the or to . Kotlin Android official documentation this post Lazy delegate The Kotlin standard library contains many useful delegates, for example the function can be used to create a property initialized only when it’s used for the first time. This delegate can be useful to easily initialize a property managed using Dagger: lazy private val navigationController by ( as GithubApp).component.navigationController() lazy { applicationContext } Using Dagger in the standard way you don’t need something similar because the property would be populated invoking an method on a component. In a you can find on I am trying to use Dagger in a simplified way, Activities and Fragments dependencies are manually retrieved from the Dagger component. inject demo project GitHub The code of the previous example can be simplified defining two extension properties to retrieve the Dagger Component from a or from a : Context Fragment val Context. : AppComponentget() = ( as GithubApp).component component applicationContext val Fragment. : AppComponentget() = . component activity component And now the property can be defined in an easy way: private val navigationController by .navigationController() lazy { component } If your class contains just a few injected field you can define them using a lazy delegate, you don’t need to define and invoke method, the property doesn’t need any annotations (so no annotation processing is involved) and it can be declared private and without keyword. inject lateinit Map delegate Another delegate defined in the Kotlin standard library is the . Using it a key-value map can be used in a static way. Sometimes we need to manage a map with a predefined set of keys, for example using Firebase Cloud Messaging the parameters sent by the server are available in a map: map delegate class MyMessagingService : FirebaseMessagingService() { override fun onMessageReceived(message: RemoteMessage?) { super.onMessageReceived(message) val data = (message?._data_ ?: _emptyMap_())._withDefault_ { "" } val title = data\["title"\] val content = data\["content"\] _print_("$title $content") } } Using the key defined as a string is error prone, I know you can define them in a constant somewhere but defining static final field (or something in a Kotlin object) is so style. We can improve this code using a class with two properties managed using map delegates: Java 1.4 class NotificationParams(val map: Map<String, String>) {val title: String by mapval content: String by map} The code can be rewritten using this class, it won’t compile if there is a typo in the field (that corresponds to the map key): override fun onMessageReceived(message: RemoteMessage?) {super.onMessageReceived(message)val data = (message?. ?: ()). "" **} data emptyMap withDefault { ** val params = NotificationParams(data) _print_("${params.title} ${params.content}") } Shared Preferences On GitHub that can be used to simplify SharedPreferences usage in Kotlin. Let’s see how a custom delegate can be very useful to write a property saved in a shared preference. First of all let’s write an extension function of the class that defines a delegate: there are already many libraries SharedPreferences fun SharedPreferences.int(defaultValue: Int = 0,key: String? = null): ReadWriteProperty<Any, Int> {return object : ReadWriteProperty<Any, Int> {override fun getValue(thisRef: Any, property: KProperty<*>) =getInt(key ?: property.name, defaultValue) override fun setValue(thisRef: Any, property: KProperty<\*>, value: Int) = edit().putInt(key ?: property.name, value).apply() }} This code is not easy to understand if you are not familiar with Kotlin constructs (and maybe even if you are familiar with them). It defines a new extension method that can be invoked on a object, this method returns a that defines how the property will be read and written. There are two optional arguments: the default value and the key used to store the value in the shared preferences (the property name is used if the key is not provided). int SharedPreferences ReadWriteProperty Using this method we can define a class with a field connected to the shared preferences: class MyClass(prefs: SharedPreferences) {var count by prefs. ()} int Every time the property is invoked the value is read (or written) from the shared preferences. We can define similar methods for the other types, to avoid copy and paste we can use a generic method (I know, this is even less readable than the previous definition): private inline fun <T> SharedPreferences.delegate(defaultValue: T,key: String?,crossinline getter: SharedPreferences.(String, T) -> T,crossinline setter: Editor.(String, T) -> Editor): ReadWriteProperty<Any, T> {return object : ReadWriteProperty<Any, T> {override fun getValue(thisRef: Any, property: KProperty<*>) =getter(key ?: property.name, defaultValue) override fun setValue(thisRef: Any, property: KProperty<\*>, value: T) = edit().setter(key ?: property.name, value).apply() } } The additional parameters are two functions (both are extension function to simplify the way they are provided when the function is invoked): delegate a getter to read the value from a object SharedPreferences a setter to write the value on an Editor This function is defined as to avoid runtime overhead, using this keyword the and parameters are not translated into a class in the bytecode (more infos are available in the ). inline getter setter official documentation And now we can easily write the methods for all the types that can be written in a shared preferences (here the fact that in Kotlin generics can be used also for the primitive types is really useful): fun SharedPreferences.int(def: Int = 0, key: String? = null) = (def, key, SharedPreferences::getInt, Editor::putInt) delegate fun SharedPreferences.long(def: Long = 0, key: String? = null) = (def, key, SharedPreferences::getLong, Editor::putLong) delegate //... These delegates can be used to write a class that stores a token and count how many times the token is saved (it’s not too useful, it’s just an example): class TokenHolder(prefs: SharedPreferences) {var token by prefs. ()private set string var count by prefs._int_() private set fun saveToken(newToken: String) { token = newToken count++ } } When is invoked we are reading the value from the shared preferences and saving that value incremented by one, something like this (but in a readable and compact form!): count++ prefs.edit().putInt("count", prefs.getInt("count", 0) + 1).apply() is an Android SDK class, using this delegate we are using it in many classes, some of them are probably classes of the business logic of the app. Many developers like to keep these classes Android-free to test them using a JVM test. Using this delegate our class is testable on the JVM even if we are using an Android SDK class. We can write a JVM test using a fake implementation that uses a map to store the values: SharedPreferences SharedPreferences @Test fun shouldCount() {val prefs = FakeSharedPreferences()val tokenHolder = TokenHolder(prefs) tokenHolder.saveToken("a") tokenHolder.saveToken("b") assertThat(tokenHolder.count).isEqualTo(2) assertThat(prefs.getInt("count", 0)).isEqualTo(2) } You can find the Kotlin version of and the original Java version in the (59 Vs 166 lines of code!). FakeSharedPreferences here Calendar repository EDIT: I created a small library based on the example of this post to use Kotlin delegates for shared preferences, you can find it on GitHub here: github.com/NaluLabs/prefs-delegates And that’s all for the first part of this post, in the we’ll see how to use Kotlin delegates to simplify Architecture Components usage (you can have a preview looking at this on GitHub). second part demo project