How to properly set up and close a `CoroutineScope...
# koin
m
How to properly set up and close a
CoroutineScope
for a Koin
Scope
?
s
Close the Koin scope
val scope = getKoin().createScope<A>() scope.close()
Close the Coroutine scope
val coroutineScope = CoroutineScope(Job() + dispatchers.Main) coroutineScope.cancel()
m
Thanks Saul. Would it be better to use a
SupervisorJob()
and
Dispatchers.Main.immediate
since that it what
ViewModel.viewModelScope
uses? Maybe also use
by lazy
since there is no point creating the scope unnecessarily.
Here’s what I have so far regarding Android’s Navigation Graphs.
Copy code
scope(navQualifier(R.id.nav_item)) {
    scoped { (coroutineScope: CoroutineScope) ->
        MyModel(someArg = get(), coroutineScope)
    }
}

// fragment
val viewModel by navGraphInstances<MyModel>(R.id.nav_item)

// common code
inline fun <reified T : Any> Fragment.navGraphInstances(
    @IdRes navGraphId: Int
): Lazy<T> = lazy {
    val holder by navGraphViewModels<NavGraphScopeHolder>(navGraphId) {
        object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T =
                NavGraphScopeHolder(navGraphId) as T
        }
    }
    holder.scope.get { parametersOf(holder.viewModelScope) }
}

class NavGraphScopeHolder(@IdRes navGraphId: Int) : ViewModel() {

    val scope = GlobalContext.get().getOrCreateScope(
        navScopeId(navGraphId),
        navQualifier(navGraphId)
    )

    override fun onCleared() {
        scope.close()
    }
}

fun navQualifier(navGraphId: Int) = named("NavQualifier (NavGraphId@$navGraphId)")

fun navScopeId(navGraphId: Int): ScopeID = "NavScopeId (NavGraphId@$navGraphId)"
s
I think for this case SupervisorJob + Dispatchers.Main.intermediate would be the correct configuration for this situation. Is it possible to use lateinit var instead of initializing by lazy?
m
I figured anyway, I’m passing the coroutineScope to the model, so my concern doesn’t make sense!
s
Yeah. That’s true.
m
Also realised, in the above example, there is no need to cancel the
viewModelScope
because that is done for us since we are making use of Android’s
ViewModel
114 Views