Skip to content

Instantly share code, notes, and snippets.

@longv
Created February 11, 2021 12:34
Show Gist options
  • Save longv/cc119468257245edaff7c857e5d5bdb3 to your computer and use it in GitHub Desktop.
Save longv/cc119468257245edaff7c857e5d5bdb3 to your computer and use it in GitHub Desktop.
Lifecycle-aware Lazy
fun <T> LifecycleOwner.lifecycleAwareLazy(initializer: () -> T): Lazy<T> = LifecycleAwareLazy(this, initializer)
private object UninitializedValue
class LifecycleAwareLazy<out T>(
private val owner: LifecycleOwner,
initializer: () -> T
) : Lazy<T>, Serializable, LifecycleObserver {
private var initializer: (() -> T)? = initializer
private var _value: Any? = UninitializedValue
@Suppress("UNCHECKED_CAST")
override val value: T
@MainThread
get() {
if (_value === UninitializedValue) {
_value = initializer!!()
attachToLifecycle()
}
return _value as T
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun resetValue() {
_value = UninitializedValue
detachFromLifecycle()
}
private fun attachToLifecycle() {
if (getLifecycleOwner().lifecycle.currentState == Lifecycle.State.DESTROYED) {
throw IllegalStateException("Initialization failed because lifecycle has been destroyed!")
}
getLifecycleOwner().lifecycle.addObserver(this)
}
private fun detachFromLifecycle() {
getLifecycleOwner().lifecycle.removeObserver(this)
}
private fun getLifecycleOwner() = when (owner) {
is Fragment -> owner.viewLifecycleOwner
else -> owner
}
override fun isInitialized(): Boolean = _value !== UninitializedValue
override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment