【问题标题】:Emit null from Observable in RxJava在 RxJava 中从 Observable 发出 null
【发布时间】:2019-01-27 09:46:23
【问题描述】:

我已经尝试了很长一段时间,但我无法专注于在 RxJava 和 Kotlin 中处理空值

我有一个 Room 数据库,它从数据库中返回一些实体(主题)的列表。如果列表为空,我需要从列表中随机选择一项或处理不同的操作。

在阅读了关于 SO 的各种答案并尝试了不同的方法之后。我尝试使用Optional:

fun getRandomTopic(): Single<Optional<Topic>> {
        return topicDao.getAll().flatMap { topics ->
            if (topics.isEmpty()) {
                Single.just(Optional.ofNullable(null))
            }

            val index = (Math.random() * topics.size).toInt()
            Single.just(Optional.of(topics[index]))
        }
    }

在我的活动中观察到了这个功能:

viewModel.getRandomTopic()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe { result ->
                    if (result.isPresent) {
                        viewModel.currentTopic.postValue(result.get())
                    } else {
                        Toast.makeText(this, "No topic found", Toast.LENGTH_SHORT).show()
                    }
                })

但是,这总是会触发空指针异常或IndexOutOfBoundsException:

io.reactivex.exceptions.OnErrorNotImplementedException: Index: 0, Size: 0
        at io.reactivex.internal.functions.Functions$14.accept(Functions.java:229)
        at io.reactivex.internal.functions.Functions$14.accept(Functions.java:226)
        at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:44)
        at io.reactivex.internal.operators.single.SingleObserveOn$ObserveOnSingleObserver.run(SingleObserveOn.java:79)
        at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:111)
        at android.os.Handler.handleCallback(Handler.java:761)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6523)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
     Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.get(ArrayList.java:411)
        at cz.xxx.TopicViewModel$getRandomTopic$1.apply(TopicViewModel.kt:31)
        at cz.xxx.TopicViewModel$getRandomTopic$1.apply(TopicViewModel.kt:17)

条件好像

if (topics.isEmpty()) {
       Single.just(Optional.ofNullable(null))
}

以某种方式被忽略,即使数组为空,语句也会继续。我在这里做错了什么?

【问题讨论】:

    标签: android kotlin rx-java2


    【解决方案1】:

    您基本上已经描述了问题所在。如果您查看 Android Studio 中的源代码,表达式Single.just(Optional.ofNullable(null)) 不会被评估为.flatMap() 的返回值。

    只有 lambda 的最后一个值是。我建议您写下类似return@something 的返回语句,以使代码更清晰易懂。解决方案?

    fun getRandomTopic(): Single<Optional<Topic>> {
        return topicDao.getAll().flatMap { topics ->
            return@flatMap if (topics.isEmpty()) {
                Single.just(Optional.ofNullable<Topic>(null))
            } else {
                val index = (Math.random() * topics.size).toInt()
                Single.just(Optional.of(topics[index]))
            }
        }
    }
    

    【讨论】:

    • 谢谢,刚刚注意到 if 被忽略了,因为类型推断错误。
    • 调用需要 API 级别 24:java.util.Optional#ofNullable
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多