Skip to content

Instantly share code, notes, and snippets.

@bherbst
Created August 14, 2017 14:47
Show Gist options
  • Save bherbst/d5d5974a294b40a85919e9546c8b6a2d to your computer and use it in GitHub Desktop.
Save bherbst/d5d5974a294b40a85919e9546c8b6a2d to your computer and use it in GitHub Desktop.
Android LifecycleProperty delegate
/**
* A property that automatically clears its reference according to the Android lifecycle.
*
* When the value for this property is set, it will be scheduled to be cleared in the opposing
* lifecycle event. For example, a property whose value is set during `onCreate()` will be cleared
* during `onDestroy()`.
*/
class LifecycleProperty<T> : LifecycleObserver {
companion object {
private val opposingEvents = mapOf(
Lifecycle.State.INITIALIZED to Lifecycle.Event.ON_DESTROY,
Lifecycle.State.CREATED to Lifecycle.Event.ON_DESTROY,
Lifecycle.State.STARTED to Lifecycle.Event.ON_STOP,
Lifecycle.State.RESUMED to Lifecycle.Event.ON_PAUSE
)
}
private var value: T? = null
private var destroyEvent: Lifecycle.Event? = null
operator fun getValue(thisRef: LifecycleOwner, property: KProperty<*>): T
= value ?: throw LifecyclePropertyDestroyedException()
operator fun setValue(thisRef: LifecycleOwner, property: KProperty<*>, value: T) {
this.value = value
destroyEvent = opposingEvents[thisRef.lifecycle.currentState]
?: throw IllegalStateException("Value set outside of the Android lifecycle")
thisRef.lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
fun onEvent(owner: LifecycleOwner, event: Lifecycle.Event) {
if (event == destroyEvent) {
value = null
}
}
class LifecyclePropertyDestroyedException : Exception("Property accessed outside of its valid lifecycle")
}
/**
* Perform an action and ignore any exceptions raised because a property is
* being accessed after its terminal lifecycle event.
*
* @param block the action to perform
*/
inline fun <T> T.lifecycleCheck(block: T.() -> Unit): Unit {
try {
block()
} catch (e: LifecycleProperty.LifecyclePropertyDestroyedException) {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment