我只是在阅读和学习Kotlin中的协程,以便在一个小型图书馆中用于娱乐/学习。在文档中,您可以执行以下操作
GlobalScope.launch {
}
所以在我的方法中,
fun myMethod() {
GlobalScope.launch {
// do some networking code
}
}
使用GlobalScope
为图书馆启动协程是最佳实践吗?在文档中说
应用程序代码通常应使用应用程序定义的CoroutineScope,强烈建议不要在GlobalScope实例上使用异步或启动。
这显然是一个库,不一定是应用程序代码。但是我不确定这是否是与协程在后台进行联网的最佳方法。
我也尝试过
runBlocking {
async {
// do some networking code
}
}
认为runBlocking
引入了一个新的协程范围,但是我认为在这种情况下,它从其父级(即主线程)继承了该范围,因此,我得到了关于主UI线程上没有网络的例外。 / p>
答案 0 :(得分:3)
您可以创建一个挂起函数,这将强制用户自己从协程调用此函数。
如果您的方法使用withContext
,则不必担心GlobalScope
或配置范围。 withContext
只是告诉协程要使用哪个上下文(对于联网,您将需要IO
。作用域现在由用户启动它来确定。
我构造方法的方式将是:
suspend fun myMethod() = withContext(Dispatchers.IO) {
// do some networking code
}
答案 1 :(得分:1)
根据要实现的目标,甚至可以在库中使用不同的模式。
如果您的函数应该在启动一些协程后立即返回,则“最佳实践”是将函数声明为CoroutineScope
的扩展,这样您就不必必须使用全局范围:
fun CoroutineScope.launchesAndReturnsImmediately() {
// launch can be called because we are extending CoroutineScope
launch {
// some work
}
}
话虽这么说,当您在库中时,您经常不需要立即返回,因此您可以声明函数suspend
,这在消费者方面更容易掌握。那里有多个选项:
withContext
在适当的线程池上运行,或调用其他挂起函数在后台做一些工作coroutineScope
启动子协程并分解工作,但仍会暂停,直到所有子协程完成为止。suspendCoroutine
或suspendCancellableCoroutine
通过包装基于回调的异步代码来“创建”悬浮。