android - 如何将其他调度程序注入 MainCoroutineRule?
问题描述
在Google Codelab for Coroutines中,我们看到了一个MainCoroutineScopeRule
. 在规则中,它解释了该规则可以扩展到其他调度程序,除了Dispatchers.Main
:
override fun starting(description: Description?) {
super.starting(description)
// If your codebase allows the injection of other dispatchers like
// Dispatchers.Default and Dispatchers.IO, consider injecting all of them here
// and renaming this class to `CoroutineScopeRule`
//
// All injected dispatchers in a test should point to a single instance of
// TestCoroutineDispatcher.
Dispatchers.setMain(dispatcher)
}
我的问题是,我们究竟如何注入其他调度程序?这是否假设我们正在使用依赖注入?如果是这样,如果我不使用 DI 怎么办,我还能将此规则扩展到其他调度程序吗?我在kotlinx-coroutines-test库中看不到任何允许我将 设置TestCoroutineDispatcher
为其他调度程序的内容。所以,有这个:
Dispatchers.setMain(dispatcher)
...但不是这个:
Dispatchers.setIO(dispatcher) // Or Default, etc.
我是否希望重写我的suspend
函数以接收调度程序作为参数:
suspend doSomeIO(dispatcher: CoroutineDispatcher = Dispatchers.IO) {
launch(dispatcher) {
// Some long-running IO operation
}
}
解决方案
您是正确的,因为这确实假设您正在注入调度程序。如果您不使用主调度程序,则应该注入调度程序以正确测试它。
如果您想强制该特定函数位于 Dispatchers.IO 线程上,那么您编写挂起函数的方式是一种方法。但是,您最终将获得嵌套启动。
取而代之的是,我只需将调度程序传递给 viewModel,并让 viewmodel 决定如何调用挂起函数。
//Your version:
suspend fun doSomeIO(dispatcher: CoroutineDispatcher = Dispatchers.IO) {
launch(dispatcher) {
// Some long-running IO operation
}
}
class MyViewModel(val dispatcher: CoroutineDispatcher = Dispatchers.IO: ViewModel() {
init {
viewModelScope.launch {
doSomeIO(dispatcher) // here you are launching one coroutine inside the other
}
}
}
// Instead try this:
suspend fun doSomeIO() {
// Some long-running IO operation
}
class MyViewModel(val dispatcher: CoroutineDispatcher = Dispatchers.IO: ViewModel() {
init {
viewModelScope.launch(dispatcher) {
doSomeIO()
}
}
}
推荐阅读
- unity3d - 如何实例化一个独特的预制件?
- unit-testing - 普罗米修斯 CollectAndCount 总是返回 1
- javascript - 发生错误时我应该使用 process.exit(1) 吗?
- qt - QFileDialog 默认“文件类型”选择已更改
- domain-driven-design - DDD 限界上下文之间的双向通信
- python - 检查 pygame 事件队列中的特定事件
- android - 如何在 Flutter 中从基于 Arduino 的蓝牙设备接收数据
- ios - 当用户隐藏应用程序或关闭设备时,swiftui 中的自定义计时器停止在后台获取中计数
- c++ - 错误 C2910。专业化定义错误
- build - 关于在 Debian 上构建影子包的问题