0

我有一个抽象类,MediatorLiveData里面有一个对象。这个对象有很多来源,其中一个依赖于子类,并且abstract在父类中。在块中添加源init会在运行时导致 NullPointerException,因为在 init 块添加源时,它仍然是抽象的(或者我被引导相信)。

有没有办法将 aabstract LiveData用作 a 的源MediatorLiveData而不必在子类中设置该源?我只想override val完成它,因为我肯定会addSources()在将来的某个时候忘记调用该函数。

(我知道这个例子并不是做这件事最有用的方法,但我不想增加不必要的复杂性)

例子:

abstract class MyClass: ViewModel(){
    private val _myMediator = MediatorLiveData<String>()
    
    protected abstract val mySource: LiveData<String>
    
    val myObservable: LiveData<String>
        get() = _myMediator
    
    // This will cause a NullPointerException at runtime
    init{
        _myMediator.addSource(mySource){ _myMediator.value = it }
    }
    
    //This should work, but requires this to be called in child class
    protected fun addSources(){
        _myMediator.addSource(mySource){ _myMediator.value = it }
    }
}

class myChild: MyClass(){
    override val mySource = Transformations.map(myRepository.someData) { it.toString() }
    
    // This is where init { addSources() } would be called
}

在阅读了 Stachu 的回答后,我决定使用这个,我没有测试,但我认为应该可以:

abstract class MyFixedClass: ViewModel(){
    private val _myMediator: MediatorLiveData<String> by lazy{
        MediatorLiveData<String>().apply{
            addSource(mySource){ this.value = it }
        }
    }

    protected abstract val mySource: LiveData<String>

    val myObservable: LiveData<String>
        get() = _myMediator
}

class MyChild: MyFixedClass(){
    override val mySource = Transformations.map(myRepository.someData) { it.toString() }
}
4

1 回答 1

2

如何使用惰性评估,例如这样的

abstract class MyClass : ViewModel() {
    private val _myMediator = MediatorLiveData<String>()
    private val _mySource: LiveData<String> by lazy { mySource() }
    protected abstract fun mySource(): LiveData<String>
    val myObservable: LiveData<String>
        get() = _myMediator
    init {
        _myMediator.addSource(_mySource) { _myMediator.value = it }
    }
}

class myChild : MyClass() {
    override fun mySource() = Transformations.map(myRepository.someData) { it.toString() }
}
于 2020-10-01T13:17:33.080 回答