jskierbi
8/7/2017 - 5:35 PM

Neat Kotlin component for RxJava2/Android making use of Lifecycle from Android Architecture Components - a delegate with auto dispose

Neat Kotlin component for RxJava2/Android making use of Lifecycle from Android Architecture Components - a delegate with auto dispose

package com.jskierbi.autodisposable

import android.arch.lifecycle.Lifecycle
import android.arch.lifecycle.Lifecycle.Event.*
import android.arch.lifecycle.LifecycleObserver
import android.arch.lifecycle.LifecycleOwner
import android.arch.lifecycle.OnLifecycleEvent
import io.reactivex.disposables.Disposable
import io.reactivex.disposables.Disposables
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/*
 * Disposes previously stored instance of Disposable on assign. 
 * Disposes currently stored instance on chosen Lifecycle.Event
 *
 * @see https://developer.android.com/topic/libraries/architecture/lifecycle.html
 * Created by jskierbi on 07.08.17.
 */
class AutoDisposable(
  private val disposeOn: Lifecycle.Event = ON_STOP
) : ReadWriteProperty<LifecycleOwner, Disposable>, LifecycleObserver {

  init {
    if (disposeOn !in listOf(ON_PAUSE, ON_STOP, ON_DESTROY)) {
      throw IllegalArgumentException("Invalid dispose lifecycle event: $disposeOn. Please use one of: $ON_PAUSE, $ON_STOP or $ON_DESTROY")
    }
  }

  private var isObserving = false
  private var disposable = Disposables.empty()

  override fun getValue(thisRef: LifecycleOwner, property: KProperty<*>) = disposable

  override fun setValue(thisRef: LifecycleOwner, property: KProperty<*>, value: Disposable) {
    if (!isObserving) {
      thisRef.getLifecycle().addObserver(this)
      isObserving = true
    }
    disposable.dispose()
    disposable = value
  }

  @OnLifecycleEvent(ON_PAUSE)
  fun onPause() {
    if (disposeOn == ON_PAUSE) disposable.dispose()
  }

  @OnLifecycleEvent(ON_STOP)
  fun onStop() {
    if (disposeOn == ON_STOP) disposable.dispose()
  }

  @OnLifecycleEvent(ON_DESTROY)
  fun onDestroy() {
    if (disposeOn == ON_DESTROY) disposable.dispose()
  }
}
class ExampleActivity : LifecycleActivity() {

  var actionDisposable by AutoDisposable(Lifecycle.Event.ON_DESTROY) // Optional parmeter, by default ON_STOP is used

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    uiBtnFromAction.setOnClickListener {
      // Automatically disposed on assign. Automatically disposed on ON_DESTROY lifecycle event.
      actionDisposable = Disposables.fromAction { Log.d("ExampleActivity", "Disposables.fromAction(): I'm disposed!") }
    }
  }
}
class ExampleFragment : LifecycleActivity() {

  var actionDisposable by AutoDisposable()

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    uiBtnFromAction.setOnClickListener {
      // Automatically disposed on assign. Automatically disposed on ON_STOP lifecycle event.
      actionDisposable = Disposables.fromAction { Log.d("ExampleFragment", "Disposables.fromAction(): I'm disposed!") }
    }
  }
}