Skip to content

Instantly share code, notes, and snippets.

@EmmanuelGuther
Created October 25, 2019 18:20
Show Gist options
  • Select an option

  • Save EmmanuelGuther/30cd4460d310fccd46a47e674efd8b05 to your computer and use it in GitHub Desktop.

Select an option

Save EmmanuelGuther/30cd4460d310fccd46a47e674efd8b05 to your computer and use it in GitHub Desktop.
A lifecycle-aware observable that sends only new updates after subscription, used for events like navigation and Snackbar messages. This avoids a common problem with events: on configuration change (like rotation) an update can be emitted if the observer is active. This LiveData only calls the observable if there's an explicit call to setValue()…
/**
* A lifecycle-aware observable that sends only new updates after subscription, used for events like
* navigation and Snackbar messages.
*
*
* This avoids a common problem with events: on configuration change (like rotation) an update
* can be emitted if the observer is active. This LiveData only calls the observable if there's an
* explicit call to setValue() or call().
*
*
* Note that only one observer is going to be notified of changes.
*/
class SingleLiveEvent<T> : MutableLiveData<T>() {
private val pending = AtomicBoolean(false)
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
when {
hasActiveObservers() -> Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
// Observe the internal MutableLiveData
super.observe(owner, Observer { t ->
if (pending.compareAndSet(true, false)) {
observer.onChanged(t)
}
})
}
@MainThread
override fun setValue(t: T?) {
pending.set(true)
super.setValue(t)
}
/**
* Used for cases where T is Void, to make calls cleaner.
*/
@MainThread
fun call() {
value = null
}
companion object {
private const val TAG = "SingleLiveEvent"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment