我需要在我的android Application
上引用协程作用域。我做了以下事情
class TodoApplication : Application() {
private var job = Job()
private val applicationScope = CoroutineScope(Dispatchers.Main + job)
val tasksRepository: TasksRepository
get() = ServiceLocator.provideTasksRepository(this, applicationScope)
}
字符串
是这样做的吗。如果是这样,我如何取消在此作用域job.cancel()
上启动的协程
应用程序类没有onDestroy方法作为Activity
5条答案
按热度按时间jljoyd4f1#
否,GlobalScope将不适用于Application示例。
正如本文here中提到的:
不应使用GlobalScope的原因有很多:
***提升硬编码值。**如果您直接使用
GlobalScope
,则可能会对Dispatchers
进行硬编码。这是一个坏习惯!***这使得测试非常困难。**由于您的代码将在不受控制的范围内执行,因此您将无法管理由它启动的工作的执行。
*你不能像
applicationScope
那样在作用域中为所有协程内置一个通用的CoroutineContext。相反,您必须向所有由GlobalScope
启动的协程传递一个公共CoroutineContext
。因此,一个解决方案是像这样创建自己的范围:
val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
但更好的是,正如@拉曼在评论中指出的那样,使用已经提供给您的等效物:字符串
我们不需要取消这个作用域,因为只要应用程序进程还活着,我们就希望它保持活动状态,所以我们不持有对SupervisorJob的引用。我们可以使用这个作用域来运行需要比我们的应用程序中的调用作用域更长的生存期的协程。
k3fezbri2#
根据现有的答案,我提出了这个解决方案:
字符串
onLowMemory()部分在某种程度上是可选的,但似乎是一个好主意,因为未完成的作业可能会在应用程序的生命周期中一直存在,并占用系统资源。
我们不需要在
onDestroy
中取消这个作用域,因为我们希望只要应用程序进程处于活动状态,它就保持活动状态,如接受的答案中所述。2cmtqfgy3#
另一种解决方案是使用
ProcessLifecycleOwner
的lifecycleScope
:字符串
在此处检查必要的依赖项。
hmmo2u0o4#
GlobalScope将适用于Application示例,taskRepository变量的 get()方法将作为Provider Pattern使用。它不应该在应用程序示例中。可以替换为lazy方法。
e4yzc0pl5#
您可以使用
onLowMemory()
在应用程序类上释放CoroutineScope()。onLowMemory()
类似于onDestroy()
字符串
清除范围
型
onLowMemory方法来释放您可能持有的任何缓存或其他不必要的资源,系统将在从该方法返回后为您执行垃圾收集。