Ad-hoc observers for seamless logging of your live data changes

illustrated by Ada Pisarska

Ad-hoc observers

private val observers = HashMap<WeakReference<MutableLiveData<*>>, Observer<*>>()

Extension .logChanges()

fun <T> MutableLiveData<T>.logChanges(
   tag: String = "[${this}]",
   printer: ((T) -> String) = { value -> "[$tag] —> $value" }
): MutableLiveData<T> =
   apply {
       if (BuildConfig.DEBUG) {
           Observer<T> { value ->
               Log.d(tag, printer(value))
           }.also { observer ->
               this.observeForever(observer)
               observers[WeakReference(this as MutableLiveData<*>)] = observer
           }
       }
   }
val data = MutableLiveData<String>().logChanges()
val data = MutableLiveData<String>().logChanges(tag = "My Data")

What happens to ad-hoc observers?

override fun onCleared() {
   super.onCleared()
   with(observers.iterator()) {
       while (hasNext()) {
           next().apply {
               (value as? Observer<in Any>)?.let {
                   key.get()?.removeObserver(it)
               }
           }
           remove()
       }
   }
}

Is it useful only for logging changes?

fun <T> LiveData<T>.observe(function: (T) -> Unit) = this
    .apply {
        Observer<T> {
            function(it)
        }.also { observer ->
            observeForever(observer)
            observers[WeakReference(this as MutableLiveData<*>)] = observer
        }
    }
fun <T> MutableLiveData<T>.observe(function: (T) -> Unit) = (this as LiveData<T>).observe(function)

Now this is neat:

val counter = MutableLiveData<Int>()
    .logChanges(tag = "Generations:")
    .initWith(0)
    .observe { counter ->
        if (counter >= LIMIT) {
            moveToMode(State.FINISHED)
        }
    }
fun <T> MutableLiveData<T>.initWith(initialValue: T): MutableLiveData<T> = apply { value = initialValue }

That’s all folks

SwingDev Insights

We've already made over 80 products for startups. We've gained valuable knowledge and experience… Now it's time to share it!

Wojciech Fijołek

Written by

Android developer, outdoors enthusiast, BJJ blue belt.

SwingDev Insights

We've already made over 80 products for startups. We've gained valuable knowledge and experience… Now it's time to share it!