MutableLiveData 是从 LiveData 扩展而来的。 LiveData 的受保护方法只能由自身或子类处理。所以在这种情况下,作为 LiveData 子类的 MutableLiveData 可以访问这些受保护的方法。
你想做的是观察一个实例,看看是否有任何变化。但与此同时,您不希望任何“局外人”改变您正在观察的那个实例。从某种意义上说,这会产生一个问题,因为您希望有一个可更改的对象来更新任何新状态,而不是可更改的,以确保任何不应该更新此实例的人。这两个特性相互冲突,但可以通过创建一个额外的层来解决。
因此,您要做的就是使用可以访问其方法的类来扩展您的类 LiveData。子层,在本例中为 MutableLiveData,能够访问其父层 (/super) 的受保护方法。
现在您开始创建实例,并创建 MutableLiveData 的观察者实例。同时,您创建一个引用同一实例的 LiveData 实例。因为 MutableLiveData 扩展了 LiveData,所以任何 MutableLiveData 实例都是 LiveData 对象,因此可以被 LiveData 变量引用。
现在这个技巧几乎完成了。您只公开 LiveData 实例,没有人可以使用其受保护的方法,也不能将其转换为超级(可能在编译时,但它不会运行:运行时错误)。并且您将实际的子类实例保持为私有,因此它只能由拥有该实例的人使用实例的方法进行更改。
//create instance of the sub class and keep this private
private val _name: MutableLiveData<String> = MutableLiveData<String>()
//create an instance of the super class referring to the same instance
val name: LiveData<String> = _name
//assign observer to the super class, being unable to change it
name.value.observe(.....)
现在超类会在应用任何更改时发出通知。
//change the instance by using the sub class
_name.postValue(...)
//or _name.setValue(...)
块引用
一般来说,这种继承形式(增加某些方法的可见性是唯一的变化)是一种众所周知的做法吗?在哪些情况下它可能有用(假设我们可以访问所有代码)?
是的,这是众所周知的,上面描述的是一种常见的情况。删除观察者模式,并将其设置为 set/get 形式将同样受益。取决于你在哪里实现它,最终没有黄金法则。