Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coroutine scope on Application class android

Tags:

I need a reference to coroutine scope on my android Application. i did the following

class TodoApplication : Application() {
    private var job = Job()
    private val applicationScope = CoroutineScope(Dispatchers.Main + job)

    val tasksRepository: TasksRepository
        get() = ServiceLocator.provideTasksRepository(this, applicationScope)

}

Is this the way to do it. If so how can I cancel coroutines launched on this scope job.cancel()

Application class don't have onDestroy method as Activities

like image 834
Emmanuel Mtali Avatar asked Apr 16 '20 17:04

Emmanuel Mtali


People also ask

What is coroutine scope Android?

A coroutine is a concurrency design pattern that you can use on Android to simplify code that executes asynchronously. Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages.

How do you define coroutine scope?

CoroutineScope is an interface with a single property coroutineContext . Therefore, we can make a class implement this interface and just directly call coroutine builders in it. class SomeClass : CoroutineScope { override val coroutineContext: CoroutineContext = Job() fun onStart() { launch { // ... } } }

What are different scopes in coroutines?

There are basically 3 scopes in Kotlin coroutines: Global Scope. LifeCycle Scope. ViewModel Scope.

Should you inject an application-scoped coroutinescope in some classes?

Following coroutine’s best practices, you might need to inject an application-scoped CoroutineScope in some classes to launch new coroutines that follow the app lifecycle or to make certain work outlive the caller’s scope.

How to use Kotlin coroutine in Android development?

To use Kotlin Coroutine, we need to have the appropriate scope defined. The tricky bit of it is, we have to remember to create, and stop them. In view of that, the Google Android development team has provided us with some Coroutine Scopes that are aware of its lifecycle.

How to create a coroutine that will outlive the ViewModel's scope?

If the coroutine needs to outlive the ViewModel 's scope, check out the Creating coroutines in the business and data layer section. Note: Views should trigger coroutines for UI-related logic. For example, fetching an image from the Internet or formatting a String.

What does withcontext do in a coroutine?

If a class is doing long-running blocking operations in a coroutine, it's in charge of moving the execution off the main thread using withContext. This applies to all classes in your app, regardless of the part of the architecture the class is in.


2 Answers

NO , GlobalScope will NOT be suitable for Application instance.

As mention here in this article here:


There are multiple reasons why you shouldn’t use GlobalScope:

  • Promotes hard-coding values. It might be tempting to hardcode Dispatchers if you use GlobalScope straight-away. That’s a bad practice!

  • It makes testing very hard. As your code is going to be executed in an uncontrolled scope, you won’t be able to manage execution of work started by it.

  • You can’t have a common CoroutineContext for all coroutines built into the scope as we did with the applicationScope. Instead, you’d have to pass a common CoroutineContext to all coroutines started by GlobalScope.


So, one solution for this is to create your own scope like this: val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) But better yet, as pointed out by @Raman in the comments, use the equivalent that's already available to you:

kotlinx.coroutines.MainScope()

We don’t need to cancel this scope since we want it to remain active as long as the application process is alive, so we don’t hold a reference to the SupervisorJob. We can use this scope to run coroutines that need a longer lifetime than the calling scope might offer in our app.

like image 81
Ali Abu Harb Avatar answered Sep 24 '22 17:09

Ali Abu Harb


GlobalScope will be suitable for Application instance.The get() method of taskRepository variable will work as Provider Pattern. It shouldn't be in app instance. It can be replace with lazy method.

like image 2
Aung Ye Htet Avatar answered Sep 22 '22 17:09

Aung Ye Htet