Created
August 14, 2017 14:47
-
-
Save bherbst/d5d5974a294b40a85919e9546c8b6a2d to your computer and use it in GitHub Desktop.
Android LifecycleProperty delegate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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