我有一个带有Room数据库的简单Android应用程序,我正在尝试使用RxJava对@Insert
查询进行响应,但是我无法正确链接这些调用。
这是调用插入的我的视图模型方法:
fun insertTopic(): Single<Long> {
val topic = Topic(null, topicText.value!!, difficulty.value!!, false)
return Single.create<Long> { Observable.just(topicDao.insert(topic)) }
}
这是我的活动中触发保存操作的代码:
disposable.add(RxView.clicks(button_save)
.flatMapSingle {
viewModel.insertTopic()
.subscribeOn(Schedulers.io())
}.observeOn(AndroidSchedulers.mainThread())
.doOnError { Toast.makeText(this, "Error inserting topic", Toast.LENGTH_SHORT).show() }
.subscribe { id ->
// NOT INVOKED
hideKeyboard()
Toast.makeText(this, "Topic inserted. ID: $id", Toast.LENGTH_SHORT).show()
this.finish
})
当我单击按钮时,将保存实体,但不会调用任何订阅代码(不显示吐司)。有人可以向我指出我在做什么错吗?我是RX Java的新手。
答案 0 :(得分:4)
问题在于Single.create
的使用不正确。无需将topicDao.insert(topic)
包装到Observable
中。此外,您正在手动实现新的Single,这意味着您必须将结果ID传递给@NonNull SingleEmitter<T> emitter
参数。但是这里不需要使用Single.create
。
Single.fromCallable
正是您需要的:
fun insertTopic(): Single<Long> = Single.fromCallable {
val topic = Topic(null, topicText.value!!, difficulty.value!!, false)
return@fromCallable topicDao.insert(topic)
}
请注意,我在lambda内创建了topic
对象,以便它不会在闭包中捕获。另外请记住,如果您在执行lambda代码期间取消订阅fromCallable
,则UndeliverableException
may throw Single
。在您的特定情况下,它可能永远不会发生,但是您应该了解RxJava2 error handling设计。