Necesito una referencia al alcance de la rutina en mi Application de Android. hice lo siguiente
class TodoApplication : Application() { private var job = Job() private val applicationScope = CoroutineScope(Dispatchers.Main + job) val tasksRepository: TasksRepository get() = ServiceLocator.provideTasksRepository(this, applicationScope) } Es esta la manera de hacerlo. Si es así, ¿cómo puedo cancelar las corrutinas lanzadas en este ámbito job.cancel()
La clase de aplicación no tiene el método onDestroy como actividades
GlobalScope será adecuado para la instancia de la aplicación. El método get( ) de la variable taskRepository funcionará como patrón de proveedor . No debería estar en la instancia de la aplicación. Se puede reemplazar con el método perezoso .
NO, GlobalScope NO será adecuado para la instancia de la aplicación.
Como se menciona aquí en este artículo aquí :
Hay varias razones por las que no debería usar GlobalScope:
Promueve valores de codificación rígida. Puede ser tentador codificar Dispatchers si usa GlobalScope de inmediato. ¡Es una mala práctica!
Hace que las pruebas sean muy difíciles. Como su código se ejecutará en un ámbito no controlado, no podrá administrar la ejecución del trabajo iniciado por él.
No puede tener un CoroutineContext común para todas las corrutinas integradas en el alcance como lo hicimos con applicationScope . En su lugar, tendría que pasar un CoroutineContext común a todas las corrutinas iniciadas por GlobalScope .
¡Entonces, la solución para esto es crear su propio alcance!
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)No necesitamos cancelar este alcance ya que queremos que permanezca activo mientras el proceso de solicitud esté activo, por lo que no mantenemos una referencia a SupervisorJob. Podemos usar este alcance para ejecutar corrutinas que necesitan una vida útil más larga que la que podría ofrecer el alcance de llamada en nuestra aplicación.
Puede usar onLowMemory() para liberar CoroutineScope() en la clase de aplicación. onLowMemory() es similar a onDestroy()
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)despejar el alcance
override fun onLowMemory() { super.onLowMemory() applicationScope.cancel() }onLowMemory para liberar cachés u otros recursos innecesarios que pueda tener. El sistema realizará una recolección de elementos no utilizados después de regresar de este método.
Basado en las respuestas existentes, se me ocurrió esta solución:
class YourApplication : Application() { companion object { var applicationScope = MainScope() } override fun onLowMemory() { super.onLowMemory() applicationScope.cancel("onLowMemory() called by system") applicationScope = MainScope() } }La parte onLowMemory() es algo opcional, pero parece una buena idea, ya que los trabajos inconclusos podrían quedarse allí durante la vida útil de su aplicación y utilizar los recursos del sistema.