kotlin 在 onNext 或不应为 null 的 BehaviorSubject 中传递 mutableList

ant*_*009 7 kotlin rx-java2

Kotlin 1.3.72,RxJava2

我有以下代码,我试图避免使用 !! 运算符,但不确定为什么它认为该值为 null,我需要使用安全调用运算符。

以后我得用!!这是不好的做法。为什么这会是空的,因为我已经声明了任何可以为空的类型?

class SharedViewModel : ViewModel() {
    private val compositeDisposable = CompositeDisposable()
    private val imageSubject = BehaviorSubject.create<MutableList<Photo>>()
    private val selectedPhotos = MutableLiveData<List<Photo>>()

    init {
        imageSubject.subscribeBy {
            selectedPhotos.value = it
        }.addTo(compositeDisposable)
    }

    fun getSelectedPhotos(): LiveData<List<Photo>> {
        return selectedPhotos
    }

    fun addPhotos(photo: Photo) {
        // Not sure why I need the safe-call operator here
        imageSubject.value?.add(photo)
        // Using the !! is bad practice and would like to avoid it
        imageSubject.onNext(imageSubject.value!!)

        // This is how I am currently handling it, but just wondering why the value would be null when it is not a nullable type?
        if(imageSubject.value != null) {
            imageSubject.onNext(imageSubject.value ?: mutableListOf())
        }
    }
}    
Run Code Online (Sandbox Code Playgroud)

=== 更新 =====

我做了一些更改和更新。我的最后一个使用 let 。

fun addPhotos(photo: Photo) {
        imageSubject.value?.add(photo)

        // Original
        imageSubject.onNext(imageSubject.value!!)

        // First Attempt
        if(imageSubject.value != null) {
            imageSubject.onNext(imageSubject.value ?: mutableListOf())
        }

        // Final Attempt
        imageSubject.value?.let {
            imageSubject.onNext(it)
        }
    }
Run Code Online (Sandbox Code Playgroud)

只是另一个问题:将某些内容添加到 BehaviourSubjectimageSubject.value?.add(photo)然后立即使用 onNext 发出该值是一种好习惯imageSubject.onNext(it)吗?

Fra*_*del 1

后来我必须使用!! 这是不好的做法。为什么这是空的,因为我已经声明任何东西都是可为空的类型?

valueinBehaviorSubject可以为空,你可以检查Java代码,因为它@Nullable里面有注释。正如@skywall所说。

这就是为什么您需要在访问时定义 safe call like?或 bang like 。!!BehaviorSubject.value

还有一个问题:将某些内容添加到 BehaviourSubject imageSubject.value?.add(photo) 中,然后立即使用 onNext imageSubject.onNext(it) 发出该值,这是一种好的做法吗?

默认情况下,BehaviorSubject具有空值。因此,当您未设置任何默认值或未在您的 上发出某些内容时BehaviorSubject,它将始终具有空值。

imageSubject.value返回 null,因此add不会调用该方法。?请注意,您在调用方法之前定义了安全调用add

所以,结论是两行代码不会发出任何东西。

来自你的评论

创建一个具有初始值的BehaviorSubject可以解决这个问题吗?或者我可以在代码中做更多的事情来确保安全而不需要!!?

您可以BehaviorSubject像这样定义一个初始值

val imageSubject: BehaviorSubject<MutableList<Photo>> =
        BehaviorSubject.createDefault(mutableListOf(photo1, photo2))
Run Code Online (Sandbox Code Playgroud)

在这里了解更多信息

但是,定义默认值BehaviorSubject不会使value变得不可为空,因为它被设计为接收可为空对象。

所以,为了让你不关心安全调用或爆炸,你可以这样做

class SharedViewModel : ViewModel() {
    private val compositeDisposable = CompositeDisposable()
    private val imageSubject = BehaviorSubject.create<MutableList<Photo>>()
    private val selectedPhotos = MutableLiveData<List<Photo>>()
    private val photos = mutableListOf<Photo>() // Add this line

    ...

    fun addPhotos(photo: Photo) {
        photos.add(photo)
        imageSubject.onNext(photos)
    }
}   
Run Code Online (Sandbox Code Playgroud)