I have a DialogFragment that executes some db dele...
# coroutines
f
I have a DialogFragment that executes some db delete operation (via its own ViewModel). Since a dialog dismisses immediately when you click a button, it makes sense to use applicationScope instead of viewModelScope, correct?
Copy code
class DeleteAllCompletedViewModel @ViewModelInject constructor(
    private val taskDao: TaskDao,
    @ApplicationScope private val applicationScope: CoroutineScope
) :
    ViewModel() {

    fun deleteCompletedTasks() = applicationScope.launch {
        taskDao.deleteCompletedTasks()
    }
}
i
Or use
launch(NonCancellable)
f
Thanks, but the article by Manuel Vivo advises against this quite strongly: https://medium.com/androiddevelopers/coroutines-patterns-for-work-that-shouldnt-be-cancelled-e26c40f142ad#aa9c
i
Most of those downsides don't apply to this particular case, but I agree with the general principle there
l
I'd use WorkManager for that, or a custom idempotent and tested mechanism
f
It doesn't apply because I'm calling the dao directly and we don't expect to get any weird behavior from Room? I guess if I had a repository in between it would already be problematic.
Regarding WorkManager, I am not sure if I should use it for an operation that will probably take only a few milliseconds
l
One could argue that since WorkManager implies writing to a db, it doesn't make sense to use it for a trivial db operation (single query with tiny tiny implications like a delete operation). In that case, launching a fire and forget coroutine in the
GlobalScope
or a custom
AppScope
might be the most pragmatic solution.
f
Globalscope would be easiest, but it's also discouraged in the article above. So I've created my own applicationScope but it feels kinda pointless 😆
l
GlobalScope is still there for a reason, and can suit your particular use case, though it's almost never a good solution for the vast majority of coroutines use cases (shareIn excepted)
i
The only actual concern that applies here is the testing story - can you assert that the deletion occurs. GlobalScope or
NonCancellable
means you rely on the signal from the database to know when that operation finishes, while injecting some scope lets you wait for its work to complete. If you aren't doing that specific kind of testing though, then the shortest, most concise code gets my vote 🤷
l
One can call
join()
on
GlobalScope.launch { … }
no problem