Another question that I've been putting off for a ...
# coroutines
c
Another question that I've been putting off for a while is what to use instead of globalscope for long running operations tied to my android apps lifecycle. I've read https://manuelvivo.dev/coroutines-cancellation-exceptions-4 and so basically what I'm doing now is
Copy code
class RollerToasterApplication : Application() {
  private val job = SupervisorJob()
  private val appScope = CoroutineScope(Dispatchers.Default + job)
  private val appStateHolder = AppStateHolder(appScope)

// onCreate() calls appStateHolder.initialize()
then in AppStateHolder.kt I have
Copy code
class AppStateHolder(
    val appScope: CoroutineScope
) {
  fun initialize() {
    appScope.launch {
...
Any critiques with that approach... I think it seems to make sense and it is testable since the scope isn't being hardcode in AppStateHolder?
y
It's possible (likely?) for your app process to sometimes stay alive, even after activities and services have stopped. What is the type of the work you are doing? And why is it not tied to some activity, service or work lifecycle?
If it's a long running operation, could you schedule it with WorkManager (possibly expedited)?
c
It's global app state. So I want to read user pref values from disk with my application coroutine scope.
I'm not doing any "long running work" that should be elevated to work manager, foreground service, etc.
y
Can't you do that within some view model or service scope?
c
I was going to do it to maybe my activity (since im using compose) I pretty much have minimal (2) activities. but I need it shared across the both of them. I was originally going to use some sharedViewModel scope, etc. But for this project we're moving away from VMs, android-navigation-compose etc. So a lot of those freebie scopes go away.
From that article from manuel on the google team it seems reasonable to declare an applicationScope
y
Yep, depending on your view of very important work. And that it's short lived, not a way around getting backgrounded.
externalScope.launch { // if this can throw an exception, wrap inside try/catch // or rely on a CoroutineExceptionHandler installed // in the externalScope's CoroutineScope veryImportantOperation()
c
yeah. its not long running work. its just short work that legitimately does make sense to do at the application/process scope. i currently am using GlobalScope.launch() 🙈 , and it works fine. so just trying to create my own app scope, and therefore seeing if anyone has critiques of my code above. I never know whether to inject a coroutineScope, or context or whatever. so just trying to get a sanity check here. 😄
👍🏻 1
a
FWIW
DataStore
accepts a
CoroutineScope
directly in its constructor, and in Now in Android we inject a singleton
CoroutineScope
for it: https://github.com/android/nowinandroid/blob/447cd7eba311c9cb4b4f302bf632fe8bd4e97[…]ples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt
👀 1
c
very intersting. i gotta see what that gets me. I suppose this was done in datastore to improve the testing story?