web-dev-qa-db-fra.com

Pourquoi existe-t-il une sous-classe MutableLiveData distincte de LiveData?

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)?

51

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 .

82
Sneh Pandya

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
}
0
Ananth Raj Singh