【发布时间】:2019-10-11 20:21:33
【问题描述】:
我正在使用 rxKotlin、MVVM + Clean Architecture 创建离线第一个应用程序作为我的副项目,昨天我决定通过使用转换器摆脱样板 subscribeOn 和 observeOn。我很快意识到转换器的应用功能被忽略了。
这是我的基本可完成用例(交互器)的代码:
abstract class CompletableUseCase(private val transformer: CompletableTransformer) {
abstract fun createCompletable(data: Map<String, Any>? = null) : Completable
fun completable(data: Map<String, Any>? = null) : Completable {
return createCompletable(data).compose(transformer)
}
}
这里是特定交互器的实现:
class SaveRouteInteractor(
transformer: CompletableTransformer,
private val routeRepository: RouteRepository
) : CompletableUseCase(transformer) {
companion object {
private const val PARAM_ROUTE = "param_route"
}
fun saveRoute(route: Route) : Completable {
val data = HashMap<String, Route>()
data[PARAM_ROUTE] = route
return completable(data)
}
override fun createCompletable(data: Map<String, Any>?): Completable {
val routeEntity = data?.get(PARAM_ROUTE)
routeEntity?.let {
return routeRepository.saveRoute(routeEntity as Route)
} ?: return Completable.error(IllegalArgumentException("Argument @route must be provided."))
}
}
我的自定义转换器被传递给 SaveRouteInteractor 的构造函数:
class IOCompletableTransformer(private val mainThreadScheduler: Scheduler) : CompletableTransformer {
override fun apply(upstream: Completable): CompletableSource {
return upstream.subscribeOn(Schedulers.io()).observeOn(mainThreadScheduler)
}
}
以及RouteRepository方法的实现:
override fun saveRoute(route: Route): Completable {
return localRouteSource.saveRoute(route)
.flatMap { localID ->
route.routeId = localID
remoteRouteSource.saveRoute(route)
}
.flatMapCompletable { localRouteSource.updateRouteID(route.routeId, it) }
}
我使用 Room 作为我的本地源,所以在我的 ViewModel 中调用保存交互器后,我收到 IlligalStateException,告诉我不允许访问主线程上的数据库。
也许我遗漏了一些东西,但似乎转换功能被忽略了。我调试了这个方法,它正在将 subscribeOn 和 observeOn 应用到上游。
提前感谢您的帮助, 节奏!
【问题讨论】: