使用 RXJava 监听 Room 数据库插入

Listening to Room database insert with RXJava

我有一个带有 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)) }
    }

这是我 activity 中触发保存操作的代码:

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
            })

当我单击该按钮时,实体已保存,但订阅代码的 none 被调用(未显示 toast)。有人可以指出我做错了什么吗?我对 RX 还很陌生 java.

问题在于 Single.create 的使用不正确。没有必要将 topicDao.insert(topic) 包装成 Observable。此外,您正在手动实施 new 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 对象,因此它不会在闭包中被捕获。还要记住 fromCallable may throw UndeliverableException if you unsubscribe from Single during the lambda code execution. It will probably never happen in your specific case, but you should understand RxJava2 error handling 设计。