这两者有什么区别呢?
我正在学习一个教程,老师说我们需要一个范围,只要应用程序存在,我们就需要用SupervisorJob手动创建这个范围。GlobalScope不也做同样的事情吗?
我对此进行了研究,但找不到合适的解释。谢谢。
发布于 2022-09-23 13:45:33
这两个具体示例的不同之处在于,不能取消GlobalScope,但另一个可以取消。当您在用cancel()构造函数创建的CoroutineScope上调用CoroutineScope()时,它的所有子协同都会被取消。
如果您尝试将GlobalScope抛出一个IllegalStateException,因为它没有任务作为它启动的协同工作的父级。
当您调用CoroutineScope()而不传递作业时,它会自动获得一个泛型作业作为其协同线的父函数。这样的通用父作业将取消所有的子作业,如果其中任何一个失败的话。如果您显式地使用SupervisorJob(),那么如果它的任何子级失败,它们将不会导致所有的兄弟姐妹被取消。这是一种类似于GlobalScope的行为,因为GlobalScope协同机制没有可以通过共享父级取消的兄弟姐妹。
之所以不鼓励GlobalScope,是因为它没有监督能力。它应该只用于应该在应用程序会话的整个生命周期内运行的协同机制。但是,如果你做的重要工作不应该在Android上被取消,协同并不是一个好的选择,因为它们没有处理你的应用程序在后台的情况。在这种情况下,您应该使用服务或WorkManager来代替。因此,GlobalScope的实际合法用例,或任何从未取消的CoroutineScope,都是极为罕见的。
我认为他们加入@DelicateCoroutinesApi的原因是很多人滥用了GlobalScope。(可能是因为他们在初学者文档中不幸地使用了coroutines。)使用CoroutineScope(SupervisorJob())或CoroutineScope(Dispatchers.IO)等而不是GlobalScope来绕过警告是不正确的,因为所做的只是屏蔽警告而不更改行为,而不是创建冗余的CoroutineScope。如果您对GlobalScope有合法的使用,则应该使用@OptIn(DelicateCoroutinesApi::class)来取消警告。
https://stackoverflow.com/questions/73826229
复制相似问题