Skip to content

Instantly share code, notes, and snippets.

@jeancsanchez
Created December 7, 2023 18:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeancsanchez/0d2fe3c677330e335f5740bcd5b3ca29 to your computer and use it in GitHub Desktop.
Save jeancsanchez/0d2fe3c677330e335f5740bcd5b3ca29 to your computer and use it in GitHub Desktop.
Extension for sharing ViewModels between Activities with Kotlin Koin. (Extensão para compartilhar ViewModels entre activities com Kotlin Koin).
inline fun <retified VM: ViewModel> AppCompatActivity.viewModelShared(): Lazy<VM> {
return lazy(LazyThreadSafetyMode.NONE) {
val scopeKey = this::class.getActScopeId()
var scope: Scope = getKoin().getOrCreateScope(
scopeId = scopeKey,
qualifier = StringQualifier(scopeKey)
)
lifecycle.doWhen(
onCreate = {
scope = getKoin().getOrCreateScope(
scopeId = scopeKey,
qualifier = StringQualifier(scopeKey)
)
},
onDestroy = {
if(scope.isNotClosed()) {
scope.close()
}
}
scope.get()
}
inline fun <retified VM: ViewModel, retified ACTIVITY: AppCompatActivity> AppCompatActivity.sharedViewModel(): Lazy<VM> {
return lazy(LazyThreadSafetyMode.NONE) {
val scopeKey = ACTIVITY::class.getActScopeId()
val koin = getKoin()
var scope = koin.getScopeOrNull(scopeKey)
if(scope == null) {
scope = koin.createScope(
scopeId = scopeKey,
qualifier = StringQualifier(scopeKey)
)
lifecycle.doWhen(
onDestroy = {
if (scope.isNotClosed()) {
scope.close()
}
}
)
}
}
}
inline fun <retified ACTIVITY: AppCompatActvity> Module.viewModelSharedScope(
noninline scopeSet: ScopeDSL.() -> Unit
) {
scope(
qualifier = named(ACTIVITY::class.getActScopeId()),
scopeSet = scopeSet
)
}
fun Lifecycle.doWhen(
onCreate: (() -> Unit)? = null,
onDestroy: (() -> Unit)
) {
addObserver ( object: LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
when(event) {
Lifecycle.Event.ON_CREATE -> onCreate?.invoke()
Lifecycle.Event.ON_DESTROY -> onDestroy()
else -> Unit
}
}
})
}
private fun KClass<*>.getActScopeId(): String = "${this.java.simpleName}-SharedActivityScope"
@jeancsanchez
Copy link
Author

How to use:

// MyKoinModule.kt
viewModelSharedScope<Activity1> {
    scoped {
        MyViewModel ( ... )
    }
}
// Activity1.kt
val viewModel: MyViewModel by viewModelShared()
//  Activity2.kt
val viewModel: MyViewModel by sharedViewModel<MyViewModel, Activity1>()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment