Created
February 24, 2017 01:56
-
-
Save edenman/8bf06791295793c83fe7920854de751e to your computer and use it in GitHub Desktop.
Kotlin lazy delegate that enforces single-initialization by ensuring callers are on the main thread
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
package my.package.foo | |
/** | |
* This method is just a modification of the kotlin stdlib lazy initializer, which by default uses a | |
* synchronized block to ensure no double-running of the initializer. Synchronized blocks are not | |
* particularly fast on Android so we try to avoid them when possible: in all of our cases, the | |
* lazy property is being accessed on the main thread, so it's easier to just check that we're on | |
* the main thread as a way to ensure no double-running of the initializer. | |
*/ | |
fun <T> lazyMainThread(initializer: () -> T): Lazy<T> = LazyMainThreadImpl(initializer) | |
private object UNINITIALIZED_VALUE | |
private class LazyMainThreadImpl<out T>(initializer: () -> T) : Lazy<T> { | |
private var initializer: (() -> T)? = initializer | |
private var _value: Any? = UNINITIALIZED_VALUE | |
override val value: T | |
get() { | |
checkMainThread() // Make sure this value is only ever accessed from the main thread | |
val _v1 = _value | |
if (_v1 !== UNINITIALIZED_VALUE) { | |
@Suppress("UNCHECKED_CAST") | |
return _v1 as T | |
} | |
val typedValue = initializer!!() | |
_value = typedValue | |
initializer = null | |
return typedValue | |
} | |
override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE | |
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