Il semble que MutableLiveData
diffère de LiveData
uniquement en rendant publiques les méthodes setValue()
et postValue()
, alors qu'elles sont protégées dans LiveData
.
Quelles sont certaines des raisons de créer une classe distincte pour ce changement et de ne pas simplement définir ces méthodes comme publiques dans le LiveData
lui-même?
De manière générale, cette forme d’héritage (l’augmentation de la visibilité de certaines méthodes étant le seul changement) est-elle une pratique bien connue et quels sont les scénarios où elle peut être utile (en supposant que nous ayons accès à tout le code)?
Dans LiveData - Android Documentation du développeur , vous pouvez voir que pour LiveData
, setValue()
et postValue()
les méthodes ne sont pas publiques.
Considérant que, dans MutableLiveData - Android Documentation du développeur , vous pouvez voir que, MutableLiveData
étend LiveData
en interne et également les deux méthodes magiques de LiveData
est publiquement disponible dans ceci et ils sont setValue()
& postValue()
.
setValue()
: définir la valeur et envoyer la valeur à tous les observateurs actifs, doit être appelée à partir du fil .
postValue()
: poste une tâche sur le thread principal pour remplacer la valeur définie par setValue()
, doit être appelé depuis thread d'arrière-plan .
Donc, LiveData
est immuable . MutableLiveData
est LiveData
ce qui est mutable & thread-safe .
C'est le fichier entier MutableLiveData.Java
:
package androidx.lifecycle;
/**
* {@link LiveData} which publicly exposes {@link #setValue(T)} and {@link #postValue(T)} method.
*
* @param <T> The type of data hold by this instance
*/
@SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
Donc, oui, la différence ne vient que de rendre postValue
et setValue
public.
Un cas d’utilisation que je peux rappeler de ma tête est celui de l’encapsulation avec Backing Property à Kotlin. Vous pouvez exposer LiveData
à votre fragment/activité (contrôleur d'interface utilisateur) même si vous pouvez avoir MutableLiveData
à des fins de manipulation dans votre classe ViewModel
.
class TempViewModel : ViewModel() {
...
private val _count = MutableLiveData<Int>()
val count: LiveData<Int>
get() = _count
public fun incrementCount() = _score.value?.plus(1)
...
}
De cette façon, votre contrôleur d'interface utilisateur ne pourra qu'observer les valeurs sans pouvoir les éditer. De toute évidence, votre contrôleur d'interface utilisateur peut modifier les valeurs à l'aide des méthodes publiques de TempViewModel
comme incrementCount()
.
Remarque : Pour clarifier la confusion mutable/immuable -
data class User(var name: String, var age: Int)
class DemoLiveData: LiveData<User>()
var demoLiveData: LiveData<User>? = DemoLiveData()
fun main() {
demoLiveData?.value = User("Name", 23) // ERROR
demoLiveData?.value?.name = "Name" // NO ERROR
demoLiveData?.value?.age = 23 // NO ERROR
}