我在试图找出实现带有进度的UseCase的最佳方法时遇到了问题。我看过类似的例子:
Google I / O Android应用 https://github.com/google/iosched/blob/master/shared/src/main/java/com/google/samples/apps/iosched/shared/domain/UseCase.kt
我不喜欢的是以下内容:
- 您会收到在UI中接收结果并在那里做出很多决定的信息。
- 没有进展
我认为上述内容的升级是:
Android体系结构蓝图
他们正在使用协程,现在结果在ViewModel中,效果更好。但同样:没有进展
我的问题是每个人都在使用RxJava,因为其他人都在使用它。我看到很多人认为这是“在后台执行任务”。但这对我来说太过分了。我不需要
我已经看到了一些有关协程频道的示例,但是它们确实非常难看。
所以最近我偶然发现了Roman Elizarov的这篇文章:
https://medium.com/@elizarov/callbacks-and-kotlin-flows-2b53aa2525cf
我做了这样的事情:
class ProduceValueWithProgressUseCase @Inject constructor(
private val executor: Executor
) {
operator fun invoke(): Flow<Result<Int,Int>> {
return callbackFlow {
val callback = object : CallbackProgress {
override fun onProgress(result: Int) {
offer(Result.Loading(result))
}
override fun onSuccess(result: Int) {
offer(Result.Success(result))
close()
}
override fun onError(e: Exception) {
offer(Result.Error(e))
}
}
val producer = ValueWithProgressproducer(callback)
executor.execute(producer)
awaitClose {}
}
}
}
这个想法是,“生产者”这个东西使用回调来像大多数“旧” API一样传播数据。所以我想通过流将代码传播到ViewModel,而不是在其中放置回调。像这样:
viewModelScope.launch {
produceValueWithProgressUseCase().collect {
when (it) {
is Success -> view.showWithProgressResult(it.data)
is Loading -> view.updateProgress(it.progress)
else -> view.showError()
}
}
}
是的,基本上,Flows API将为我完成工作。我什至创建了一个小应用程序来测试它,我只是在其中生成数字,并且运行良好。我不喜欢它的是:
-
必须放置太多ExperimentCoroutinesApi注释。例如此处(对不起格式):
@Suppress(“ NOTHING_TO_INLINE”) @ExperimentalCoroutinesApi 公共内联乐趣callbackFlow(@BuilderInference noinline块:暂停 ProducerScope。()-> Unit):流量= channelFlow(block)
上面的代码是文件的一部分:kotlinx.coroutines.flow.Builders.kt,来自版本:kotlinx-coroutines-core-1.3.2
- 在某些时候,我用@Preview注释打了一些东西。(老实说,不记得在哪里。这是我删除的东西。)
- 我也尝试了一点,以了解测试的进行方式,但这并不简单。您可以在Blueprinst的代码中看到相同的内容。
- 我还混合了执行任务的代码和任务本身。我的意思是callbackFlow()的用法。
所以最后我看到了某种看起来像在为明年的变革而尖叫的事情。因此,请对此发表您的想法。