阅读了很多有关此内容的内容,但仍有一些不清楚的地方。
这句话:“协程允许以同步方式编写异步代码”有点令人困惑。
协程总是异步的。他们基本上一直在线程上运行?由我们决定要声明要使用的协程哪些线程(Mainscope-它们在MainThread上运行,CoroutinesScope-它将在与UI线程不关联的一些不同线程上运行,ViewmodelScope-它们将在与Java线程无关的线程上运行)。与viewmodel相关联?)
我说对了吗?
最佳答案
他们认为,大多数Java世界以异步方式编写的传统方法是使用“回调”,这是通过添加用于成功和失败的侦听器来编写异步任务的唯一方法。
但是协程的方式略有不同。实际上,您调用了诸如delay(ms: Long)
之类的暂停函数,它似乎并不异步,因为这里没有涉及任何回调,但是在幕后,Continuation对象将代替回调工作,以便在以后需要时恢复它。
对,他们是!
对,他们是!
是的,绝对。他们实现结构化并发。
显然,是的。
public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)
它创建一个Contextt的 dispatch 者元素为CoroutineScope的Dispatchers.Main,以使子代默认分配到主线程中(未指定时),并附加一个SupervisorJob,以使其他子代不受取消一个子代的影响。不,您可以自行决定是否将CoroutineDispatcher元素提供给CoroutineContext来决定将子协程分配给哪个线程,例如,有4个默认的CoroutineDispatcher:
此外,您可以使用java.util.Executors制作自己的CoroutineDispatcher:
Executors.newFixedThreadPool(4).asCoroutineDispatcher() // Your own dispatcher max of 4-threads
除分派(dispatch)器外,CoroutineContext中还有许多其他元素。像:Job,CoroutineName,CoroutineInterceptor,CoroutineExceptionHandler等。,我建议阅读this文章,以更好地可视化CoroutineContext的一些最重要元素的情况。 CoroutineScope只是CoroutineContext的包装,它实际上有助于使用
launch
或async
启动协程,您可以通过将CoroutineContext作为参数传递来创建一个协程(如CoroutineScope(Dispatchers.Default + Job() + CoroutineName("My Coroutine"))
)。注意:CoroutineContext的所有元素本身就是一个CoroutineContext,
+
符号是CoroutineContext中定义的plus函数的重载,实际上是用左侧CoroutineContext中的元素覆盖了左侧CoroutineContext中的元素(如果左侧不存在该元素,则将其添加) )。 ViewModelScope默认实现Dispatchers.Main以启动任务,并且它们可以更改UI元素,因为只有主线程才能更改UI元素。
SideNote :您可以在启动之前更改CoroutineContext的元素(覆盖范围之一)。
例:
viewModelScope.launch(Dispatchers.Default) {
// This coroutine is launched under Dispatchers.Default (backed by a CommonPool of threads) instead of Dispatchers.Main
// but will follow cancellation as soon as lifecycle of Activity associated is destroyed as Job element is not overriden
}