LiveData-Übersicht Teil von Android Jetpack

LiveData ist eine beobachtbare Dateninhaberklasse. Im Gegensatz zu einem regulären beobachtbaren Element berücksichtigt LiveData den Lebenszyklus. Das bedeutet, dass der Lebenszyklus anderer Anwendungskomponenten wie Aktivitäten, Fragmente oder Dienste berücksichtigt wird. Dadurch wird sichergestellt, dass LiveData nur Beobachter von App-Komponenten aktualisiert, die sich in einem aktiven Lebenszyklus befinden.

Für LiveData wird ein Beobachter, der durch die Klasse Observer dargestellt wird, als aktiv betrachtet, wenn sein Lebenszyklus den Status STARTED oder RESUMED hat. LiveData benachrichtigt nur aktive Beobachter über Aktualisierungen. Inaktive Beobachter, die für die Überwachung von LiveData-Objekten registriert sind, werden nicht über Änderungen benachrichtigt.

Sie können einen Beobachter registrieren, der mit einem Objekt gekoppelt ist, das die LifecycleOwner-Schnittstelle implementiert. Durch diese Beziehung kann der Beobachter entfernt werden, wenn sich der Status des entsprechenden Lifecycle-Objekts in DESTROYED ändert. Dies ist besonders bei Aktivitäten und Fragmenten nützlich, da diese LiveData-Objekte sicher beobachten können und sich keine Gedanken über Datenlecks machen müssen. Aktivitäten und Fragmente werden sofort abgemeldet, wenn ihre Lebenszyklen gelöscht werden.

Weitere Informationen zur Verwendung von LiveData finden Sie unter Mit LiveData-Objekten arbeiten.

Die Vorteile von LiveData

Die Verwendung von LiveData bietet folgende Vorteile:

Sorgt dafür, dass die UI dem Datenstatus entspricht
LiveData folgt dem Muster des Beobachters. LiveData benachrichtigt Observer-Objekte, wenn zugrunde liegende Daten geändert werden. In diesen Observer-Objekten können Sie Ihren Code konsolidieren, um die UI zu aktualisieren. Auf diese Weise müssen Sie die UI nicht jedes Mal aktualisieren, wenn sich die Anwendungsdaten ändern, da das der Beobachter für Sie übernimmt.
Keine Speicherlecks
Beobachter sind an Lifecycle-Objekte gebunden und bereinigen diese nach dem Löschen des zugehörigen Lebenszyklus.
Keine Abstürze aufgrund angehaltener Aktivitäten
Wenn der Lebenszyklus des Beobachters inaktiv ist, z. B. bei einer Aktivität im Back-Stack, empfängt er keine LiveData-Ereignisse.
Keine manuelle Lebenszyklusbehandlung mehr
UI-Komponenten erfassen lediglich relevante Daten und werden nicht unterbrochen oder fortgesetzt. LiveData verwaltet all das automatisch, da die relevanten Statusänderungen des Lebenszyklus während der Beobachtung berücksichtigt werden.
Immer aktuelle Daten
Wenn ein Lebenszyklus inaktiv wird, erhält er die neuesten Daten, sobald er wieder aktiv wird. Beispielsweise erhält eine Aktivität, die im Hintergrund ausgeführt wurde, die neuesten Daten direkt nach der Rückkehr in den Vordergrund.
Richtige Konfigurationsänderungen
Wenn eine Aktivität oder ein Fragment aufgrund einer Konfigurationsänderung neu erstellt wird, z. B. bei einer Geräterotation, werden sofort die neuesten verfügbaren Daten empfangen.
Ressourcen freigeben
Sie können ein LiveData-Objekt mit dem Singleton-Muster erweitern, um Systemdienste zu umschließen und in Ihrer Anwendung freigeben zu können. Das LiveData-Objekt stellt einmalig eine Verbindung zum Systemdienst her. Jeder Beobachter, der die Ressource benötigt, kann dann einfach das LiveData-Objekt beobachten. Weitere Informationen finden Sie unter LiveData erweitern.

Mit LiveData-Objekten arbeiten

So arbeiten Sie mit LiveData-Objekten:

  1. Erstellen Sie eine Instanz von LiveData für einen bestimmten Datentyp. Dies erfolgt normalerweise innerhalb der Klasse ViewModel.
  2. Erstellen Sie ein Observer-Objekt, mit dem die Methode onChanged() definiert wird, die steuert, was passiert, wenn sich die auf „Hold“ gesetzten Daten des LiveData-Objekts ändern. Normalerweise erstellen Sie ein Observer-Objekt in einem UI-Controller, z. B. eine Aktivität oder ein Fragment.
  3. Hängen Sie das Objekt Observer mit der Methode observe() an das Objekt LiveData an. Für die Methode observe() wird ein LifecycleOwner-Objekt verwendet. Dadurch wird das Objekt Observer für das Objekt LiveData abonniert, sodass es über Änderungen benachrichtigt wird. Normalerweise hängen Sie das Observer-Objekt in einem UI-Controller an, z. B. in einer Aktivität oder einem Fragment.

Wenn Sie den im Objekt LiveData gespeicherten Wert aktualisieren, werden alle registrierten Beobachter ausgelöst, solange das angehängte LifecycleOwner-Element aktiv ist.

Mit LiveData können UI-Controller-Beobachter Updates abonnieren. Wenn sich die Daten des LiveData-Objekts ändern, wird die UI automatisch entsprechend aktualisiert.

LiveData-Objekte erstellen

LiveData ist ein Wrapper, der mit allen Daten verwendet werden kann, einschließlich Objekten, die Collections implementieren, z. B. List. Ein LiveData-Objekt wird normalerweise in einem ViewModel-Objekt gespeichert und über eine Getter-Methode aufgerufen, wie im folgenden Beispiel gezeigt:

Kotlin

class NameViewModel : ViewModel() {

    // Create a LiveData with a String
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    // Rest of the ViewModel...
}

Java

public class NameViewModel extends ViewModel {

// Create a LiveData with a String
private MutableLiveData<String> currentName;

    public MutableLiveData<String> getCurrentName() {
        if (currentName == null) {
            currentName = new MutableLiveData<String>();
        }
        return currentName;
    }

// Rest of the ViewModel...
}

Anfangs sind die Daten in einem LiveData-Objekt nicht festgelegt.

Weitere Informationen zu den Vorteilen und zur Nutzung der ViewModel-Klasse finden Sie in der Anleitung zu ViewModel.

LiveData-Objekte beobachten

In den meisten Fällen ist die Methode onCreate() einer App-Komponente aus den folgenden Gründen der richtige Ort, um ein LiveData-Objekt zu beobachten:

  • Damit das System keine redundanten Aufrufe über die Methode onResume() einer Aktivität oder eines Fragments sendet.
  • Um sicherzustellen, dass die Aktivität oder das Fragment Daten hat, die angezeigt werden können, sobald sie aktiv werden. Sobald eine App-Komponente den Status STARTED hat, erhält sie den neuesten Wert von den von ihr beobachteten LiveData-Objekten. Dies geschieht nur, wenn das zu beobachtende LiveData-Objekt festgelegt wurde.

Im Allgemeinen liefert LiveData Aktualisierungen nur dann, wenn sich Daten ändern, und nur an aktive Beobachter. Eine Ausnahme von diesem Verhalten besteht darin, dass Beobachter auch ein Update erhalten, wenn sie von einem inaktiven in einen aktiven Status wechseln. Wenn der Beobachter außerdem ein zweites Mal von „Inaktiv“ zu „Aktiv“ wechselt, erhält er nur dann eine Aktualisierung, wenn sich der Wert seit der letzten Aktivierung geändert hat.

Der folgende Beispielcode zeigt, wie ein LiveData-Objekt beobachtet wird:

Kotlin

class NameActivity : AppCompatActivity() {

    // Use the 'by viewModels()' Kotlin property delegate
    // from the activity-ktx artifact
    private val model: NameViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Other code to setup the activity...

        // Create the observer which updates the UI.
        val nameObserver = Observer<String> { newName ->
            // Update the UI, in this case, a TextView.
            nameTextView.text = newName
        }

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.currentName.observe(this, nameObserver)
    }
}

Java

public class NameActivity extends AppCompatActivity {

    private NameViewModel model;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Other code to setup the activity...

        // Get the ViewModel.
        model = new ViewModelProvider(this).get(NameViewModel.class);

        // Create the observer which updates the UI.
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                // Update the UI, in this case, a TextView.
                nameTextView.setText(newName);
            }
        };

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.getCurrentName().observe(this, nameObserver);
    }
}

Nachdem observe() mit nameObserver als Parameter aufgerufen wurde, wird onChanged() sofort aufgerufen, wodurch der neueste Wert bereitgestellt wird, der in mCurrentName gespeichert ist. Wenn das LiveData-Objekt keinen Wert in mCurrentName festgelegt hat, wird onChanged() nicht aufgerufen.

LiveData-Objekte aktualisieren

LiveData hat keine öffentlich verfügbaren Methoden zum Aktualisieren der gespeicherten Daten. Die Klasse MutableLiveData macht die Methoden setValue(T) und postValue(T) öffentlich verfügbar. Sie müssen diese verwenden, wenn Sie den in einem LiveData-Objekt gespeicherten Wert bearbeiten müssen. Normalerweise wird MutableLiveData in der ViewModel verwendet. Dann stellt ViewModel den Beobachtern nur unveränderliche LiveData-Objekte zur Verfügung.

Nachdem Sie die Beobachterbeziehung eingerichtet haben, können Sie den Wert des LiveData-Objekts aktualisieren, wie im folgenden Beispiel veranschaulicht, das alle Beobachter auslöst, wenn der Nutzer auf eine Schaltfläche tippt:

Kotlin

button.setOnClickListener {
    val anotherName = "John Doe"
    model.currentName.setValue(anotherName)
}

Java

button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        String anotherName = "John Doe";
        model.getCurrentName().setValue(anotherName);
    }
});

Wenn im Beispiel setValue(T) aufgerufen wird, rufen die Beobachter ihre onChanged()-Methoden mit dem Wert John Doe auf. Das Beispiel zeigt ein Betätigen einer Taste. Es kann aber aus verschiedenen Gründen die Methode setValue() oder postValue() aufgerufen werden, um mName zu aktualisieren, z. B. als Antwort auf eine Netzwerkanfrage oder den Abschluss einer Datenbanklast. Durch den Aufruf von setValue() oder postValue() werden in allen Fällen Beobachter ausgelöst und die UI aktualisiert.

LiveData mit Raum verwenden

Die Persistenzbibliothek Room unterstützt beobachtbare Abfragen, die LiveData-Objekte zurückgeben. Beobachtbare Abfragen werden als Teil eines Database Access Objects (DAO) geschrieben.

Room generiert den gesamten erforderlichen Code, um das LiveData-Objekt beim Aktualisieren einer Datenbank zu aktualisieren. Der generierte Code führt die Abfrage bei Bedarf asynchron in einem Hintergrundthread aus. Dieses Muster ist nützlich, um die in einer UI angezeigten Daten mit den in einer Datenbank gespeicherten Daten synchron zu halten. Weitere Informationen zu Room und DAOs finden Sie im Leitfaden zur persistenten Raumbibliothek.

Koroutinen mit LiveData verwenden

LiveData unterstützt Kotlin-Koroutinen. Weitere Informationen finden Sie unter Kotlin-Koroutinen mit Android-Architekturkomponenten verwenden.

LiveData in der Architektur einer App

LiveData berücksichtigt den Lebenszyklus und folgt dem Lebenszyklus von Entitäten, z. B. Aktivitäten und Fragmenten. Verwenden Sie LiveData, um zwischen diesen Lebenszyklusinhabern und anderen Objekten mit einer anderen Lebensdauer zu kommunizieren, z. B. ViewModel-Objekte. Die Hauptaufgabe von ViewModel besteht darin, UI-bezogene Daten zu laden und zu verwalten. Sie eignet sich daher hervorragend zum Speichern von LiveData-Objekten. Erstellen Sie LiveData-Objekte in der Datei ViewModel und stellen Sie damit den Status für die UI-Ebene bereit.

Aktivitäten und Fragmente sollten keine LiveData-Instanzen enthalten, da sie die Rolle der Anzeige von Daten und nicht des Hold-Status haben. Außerdem wird das Schreiben von Einheitentests vereinfacht, wenn Aktivitäten und Fragmente keine Daten speichern.

Es mag verlockend sein, LiveData-Objekte in der Datenschichtklasse zu verwenden. LiveData ist jedoch nicht für asynchrone Datenstreams ausgelegt. Sie können zwar LiveData-Transformationen und MediatorLiveData verwenden, um dies zu erreichen, dieser Ansatz hat jedoch Nachteile: Die Möglichkeit, Datenströme zu kombinieren, ist sehr begrenzt und alle LiveData-Objekte (einschließlich der durch Transformationen erstellten) werden im Hauptthread beobachtet. Der folgende Code zeigt ein Beispiel dafür, wie das Halten einer LiveData in der Repository den Hauptthread blockieren kann:

Kotlin

class UserRepository {

    // DON'T DO THIS! LiveData objects should not live in the repository.
    fun getUsers(): LiveData<List<User>> {
        ...
    }

    fun getNewPremiumUsers(): LiveData<List<User>> {
        return getUsers().map { users ->
            // This is an expensive call being made on the main thread and may
            // cause noticeable jank in the UI!
            users
                .filter { user ->
                  user.isPremium
                }
          .filter { user ->
              val lastSyncedTime = dao.getLastSyncedTime()
              user.timeCreated > lastSyncedTime
                }
    }
}

Java

class UserRepository {

    // DON'T DO THIS! LiveData objects should not live in the repository.
    LiveData<List<User>> getUsers() {
        ...
    }

    LiveData<List<User>> getNewPremiumUsers() {
    return Transformations.map(getUsers(),
        // This is an expensive call being made on the main thread and may cause
        // noticeable jank in the UI!
        users -> users.stream()
            .filter(User::isPremium)
            .filter(user ->
                user.getTimeCreated() > dao.getLastSyncedTime())
            .collect(Collectors.toList()));
    }
}

Wenn Sie Datenstreams in anderen Ebenen Ihrer App verwenden müssen, sollten Sie Kotlin-Abläufe verwenden und sie dann im ViewModel mit asLiveData() in LiveData konvertieren. Weitere Informationen zur Verwendung von Kotlin Flow mit LiveData findest du in diesem Codelab. Ziehen Sie für Codebasis, die mit Java erstellt wurde, Executors in Verbindung mit Callbacks oder RxJava in Betracht.

LiveData erweitern

Für LiveData gilt ein Beobachter als aktiv, wenn sich der Lebenszyklus des Beobachters entweder im Status STARTED oder RESUMED befindet. Der folgende Beispielcode zeigt, wie die Klasse LiveData erweitert werden kann:

Kotlin

class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
    private val stockManager = StockManager(symbol)

    private val listener = { price: BigDecimal ->
        value = price
    }

    override fun onActive() {
        stockManager.requestPriceUpdates(listener)
    }

    override fun onInactive() {
        stockManager.removeUpdates(listener)
    }
}

Java

public class StockLiveData extends LiveData<BigDecimal> {
    private StockManager stockManager;

    private SimplePriceListener listener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);
        }
    };

    public StockLiveData(String symbol) {
        stockManager = new StockManager(symbol);
    }

    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);
    }

    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);
    }
}

Die Implementierung des Preis-Listeners in diesem Beispiel umfasst die folgenden wichtigen Methoden:

  • Die Methode onActive() wird aufgerufen, wenn das LiveData-Objekt einen aktiven Beobachter hat. Das bedeutet, dass Sie mit dieser Methode die Aktualisierungen des Aktienkurses beobachten müssen.
  • Die Methode onInactive() wird aufgerufen, wenn das LiveData-Objekt keine aktiven Beobachter hat. Da keine Beobachter zuhören, gibt es keinen Grund, mit dem Dienst StockManager verbunden zu bleiben.
  • Die Methode setValue(T) aktualisiert den Wert der LiveData-Instanz und benachrichtigt alle aktiven Beobachter über die Änderung.

Sie können die Klasse StockLiveData so verwenden:

Kotlin

public class MyFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val myPriceListener: LiveData<BigDecimal> = ...
        myPriceListener.observe(viewLifecycleOwner, Observer<BigDecimal> { price: BigDecimal? ->
            // Update the UI.
        })
    }
}

Java

public class MyFragment extends Fragment {
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        LiveData<BigDecimal> myPriceListener = ...;
        myPriceListener.observe(getViewLifecycleOwner(), price -> {
            // Update the UI.
        });
    }
}

Die Methode observe() übergibt den LifecycleOwner, der mit der Ansicht des Fragments verknüpft ist, als erstes Argument. Dadurch ist dieser Beobachter an das Objekt Lifecycle gebunden, das mit dem Inhaber verknüpft ist. Das bedeutet:

  • Wenn das Lifecycle-Objekt nicht aktiv ist, wird der Beobachter auch dann nicht aufgerufen, wenn sich der Wert ändert.
  • Nach dem Löschen des Lifecycle-Objekts wird der Beobachter automatisch entfernt.

Da LiveData-Objekte den Lebenszyklus berücksichtigen, können sie von mehreren Aktivitäten, Fragmenten und Diensten gemeinsam verwendet werden. Um das Beispiel einfach zu halten, können Sie die Klasse LiveData als Singleton implementieren:

Kotlin

class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
    private val stockManager: StockManager = StockManager(symbol)

    private val listener = { price: BigDecimal ->
        value = price
    }

    override fun onActive() {
        stockManager.requestPriceUpdates(listener)
    }

    override fun onInactive() {
        stockManager.removeUpdates(listener)
    }

    companion object {
        private lateinit var sInstance: StockLiveData

        @MainThread
        fun get(symbol: String): StockLiveData {
            sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
            return sInstance
        }
    }
}

Java

public class StockLiveData extends LiveData<BigDecimal> {
    private static StockLiveData sInstance;
    private StockManager stockManager;

    private SimplePriceListener listener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);
        }
    };

    @MainThread
    public static StockLiveData get(String symbol) {
        if (sInstance == null) {
            sInstance = new StockLiveData(symbol);
        }
        return sInstance;
    }

    private StockLiveData(String symbol) {
        stockManager = new StockManager(symbol);
    }

    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);
    }

    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);
    }
}

Im Fragment können Sie sie so verwenden:

Kotlin

class MyFragment : Fragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        StockLiveData.get(symbol).observe(viewLifecycleOwner, Observer<BigDecimal> { price: BigDecimal? ->
            // Update the UI.
        })

    }

Java

public class MyFragment extends Fragment {
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        StockLiveData.get(symbol).observe(getViewLifecycleOwner(), price -> {
            // Update the UI.
        });
    }
}

Mehrere Fragmente und Aktivitäten können die MyPriceListener-Instanz beobachten. LiveData stellt nur dann eine Verbindung zum Systemdienst her, wenn einer oder mehrere davon sichtbar und aktiv sind.

LiveData transformieren

Möglicherweise müssen Sie den in einem LiveData-Objekt gespeicherten Wert ändern, bevor Sie ihn an die Beobachter senden, oder Sie müssen eine andere LiveData-Instanz basierend auf dem Wert einer anderen Instanz zurückgeben. Das Paket Lifecycle stellt die Klasse Transformations mit Hilfsmethoden bereit, die diese Szenarien unterstützen.

Transformations.map()
Wendet eine Funktion auf den im Objekt LiveData gespeicherten Wert an und gibt das Ergebnis nachgelagert weiter.

Kotlin

val userLiveData: LiveData<User> = UserLiveData()
val userName: LiveData<String> = userLiveData.map {
    user -> "${user.name} ${user.lastName}"
}

Java

LiveData<User> userLiveData = ...;
LiveData<String> userName = Transformations.map(userLiveData, user -> {
    user.name + " " + user.lastName
});
Transformations.switchMap()
Ähnlich wie bei map() wird eine Funktion auf den im Objekt LiveData gespeicherten Wert angewendet. Das Ergebnis wird entpackt und nachgelagert. Die an switchMap() übergebene Funktion muss ein LiveData-Objekt zurückgeben, wie im folgenden Beispiel gezeigt:

Kotlin

private fun getUser(id: String): LiveData<User> {
  ...
}
val userId: LiveData<String> = ...
val user = userId.switchMap { id -> getUser(id) }

Java

private LiveData<User> getUser(String id) {
  ...;
}

LiveData<String> userId = ...;
LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );

Sie können Transformationsmethoden verwenden, um Informationen über den Lebenszyklus des Beobachters zu übertragen. Die Transformationen werden nur berechnet, wenn ein Beobachter das zurückgegebene LiveData-Objekt überwacht. Da die Transformationen verzögert berechnet werden, wird lebenszyklusbezogenes Verhalten implizit übergeben, ohne dass zusätzliche explizite Aufrufe oder Abhängigkeiten erforderlich sind.

Wenn Sie der Meinung sind, dass Sie ein Lifecycle-Objekt in einem ViewModel-Objekt benötigen, ist eine Transformation wahrscheinlich die bessere Lösung. Angenommen, Sie haben eine UI-Komponente, die eine Adresse akzeptiert und die Postleitzahl für diese Adresse zurückgibt. Sie können den einfachen ViewModel für diese Komponente implementieren, wie im folgenden Beispielcode veranschaulicht:

Kotlin

class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {

    private fun getPostalCode(address: String): LiveData<String> {
        // DON'T DO THIS
        return repository.getPostCode(address)
    }
}

Java

class MyViewModel extends ViewModel {
    private final PostalCodeRepository repository;
    public MyViewModel(PostalCodeRepository repository) {
       this.repository = repository;
    }

    private LiveData<String> getPostalCode(String address) {
       // DON'T DO THIS
       return repository.getPostCode(address);
    }
}

Die UI-Komponente muss dann jedes Mal, wenn sie getPostalCode() aufruft, ihre Registrierung beim vorherigen LiveData-Objekt aufheben und sie bei der neuen Instanz registrieren. Wird die UI-Komponente neu erstellt, löst sie außerdem einen weiteren Aufruf der Methode repository.getPostCode() aus, anstatt das Ergebnis des vorherigen Aufrufs zu verwenden.

Stattdessen können Sie die Postleitzahlsuche als Transformation der Adresseingabe implementieren, wie im folgenden Beispiel gezeigt:

Kotlin

class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
    private val addressInput = MutableLiveData<String>()
    val postalCode: LiveData<String> = addressInput.switchMap {
            address -> repository.getPostCode(address) }


    private fun setInput(address: String) {
        addressInput.value = address
    }
}

Java

class MyViewModel extends ViewModel {
    private final PostalCodeRepository repository;
    private final MutableLiveData<String> addressInput = new MutableLiveData();
    public final LiveData<String> postalCode =
            Transformations.switchMap(addressInput, (address) -> {
                return repository.getPostCode(address);
             });

  public MyViewModel(PostalCodeRepository repository) {
      this.repository = repository
  }

  private void setInput(String address) {
      addressInput.setValue(address);
  }
}

In diesem Fall ist das Feld postalCode als Transformation von addressInput definiert. Wenn Ihre Anwendung einen aktiven Beobachter mit dem Feld postalCode verknüpft hat, wird der Wert des Felds neu berechnet und abgerufen, wenn sich addressInput ändert.

Dieser Mechanismus ermöglicht es niedrigeren Ebenen der App, LiveData-Objekte zu erstellen, die bei Bedarf verzögert berechnet werden. Ein ViewModel-Objekt kann ganz einfach Verweise auf LiveData-Objekte erhalten und darauf aufbauende Transformationsregeln definieren.

Neue Transformationen erstellen

Es gibt Dutzende verschiedene Transformationen, die in Ihrer Anwendung nützlich sein können, aber nicht standardmäßig bereitgestellt werden. Wenn Sie Ihre eigene Transformation implementieren möchten, können Sie die Klasse MediatorLiveData verwenden, die andere LiveData-Objekte überwacht und von ihnen ausgegebene Ereignisse verarbeitet. MediatorLiveData leitet seinen Status korrekt an das LiveData-Quellobjekt weiter. Weitere Informationen zu diesem Muster finden Sie in der Referenzdokumentation zur Klasse Transformations.

Mehrere LiveData-Quellen zusammenführen

MediatorLiveData ist eine abgeleitete Klasse von LiveData, mit der Sie mehrere LiveData-Quellen zusammenführen können. Beobachter von MediatorLiveData-Objekten werden dann immer dann ausgelöst, wenn sich die ursprünglichen LiveData-Quellobjekte ändern.

Wenn Sie beispielsweise ein LiveData-Objekt in Ihrer UI haben, das aus einer lokalen Datenbank oder einem Netzwerk aktualisiert werden kann, können Sie dem MediatorLiveData-Objekt die folgenden Quellen hinzufügen:

  • Ein LiveData-Objekt, das den in der Datenbank gespeicherten Daten zugeordnet ist.
  • Ein LiveData-Objekt, das den Daten zugeordnet ist, auf die aus dem Netzwerk zugegriffen wird.

Ihre Aktivität muss nur das Objekt MediatorLiveData beobachten, um Updates aus beiden Quellen zu erhalten. Ein detailliertes Beispiel finden Sie im Abschnitt Zusatz: Netzwerkstatus verfügbar machen des Leitfadens zur Anwendungsarchitektur.

Weitere Informationen

Weitere Informationen zur Klasse LiveData finden Sie in den folgenden Ressourcen.

Produktproben

Codelabs

Blogs

Videos