LiveData-Übersicht   Teil von Android Jetpack.

LiveData ist eine Klasse für beobachtbare Datenhalter. Im Gegensatz zu einem regulären Observablen ist LiveData zyklusbewusst, d. h., es berücksichtigt den Lebenszyklus anderer App-Komponenten wie Aktivitäten, Fragmente oder Dienste. Dadurch wird sichergestellt, dass LiveData nur App-Komponentenbeobachter aktualisiert, die sich in einem aktiven Lebenszyklusstatus befinden.

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

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

Weitere Informationen zur Verwendung von LiveData finden Sie unter LiveData-Objekte verwenden.

Vorteile von LiveData

Die Verwendung von LiveData bietet folgende Vorteile:

Sorgt dafür, dass die Benutzeroberfläche mit dem Datenstatus übereinstimmt
LiveData folgt dem Beobachtermuster. LiveData benachrichtigt Observer-Objekte, wenn sich die zugrunde liegenden Daten ändern. Sie können Ihren Code konsolidieren, um die Benutzeroberfläche in diesen Observer-Objekten zu aktualisieren. So müssen Sie die Benutzeroberfläche nicht jedes Mal aktualisieren, wenn sich die App-Daten ändern, da der Beobachter dies für Sie erledigt.
Keine Speicherlecks
Beobachter sind an Lifecycle-Objekte gebunden und bereinigen sich selbst, wenn der zugehörige Lebenszyklus zerstört wird.
Keine Abstürze aufgrund angehaltener Aktivitäten
Wenn der Lebenszyklus des Beobachters inaktiv ist, z. B. bei einer Aktivität im Backstack, werden keine LiveData-Ereignisse empfangen.
Keine manuelle Lebenszyklusverwaltung mehr
UI-Komponenten beobachten nur relevante Daten und beenden oder setzen die Beobachtung nicht fort. LiveData verwaltet all das automatisch, da es während der Beobachtung über die relevanten Änderungen des Lebenszyklusstatus informiert ist.
Immer aktuelle Daten
Wenn ein Lebenszyklus inaktiv wird, erhält er die neuesten Daten, sobald er wieder aktiv wird. Beispiel: Eine Aktivität, die sich im Hintergrund befand, erhält die neuesten Daten direkt, nachdem sie wieder in den Vordergrund gewechselt ist.
Richtige Konfigurationsänderungen
Wenn eine Aktivität oder ein Fragment aufgrund einer Konfigurationsänderung wie der Gerätedrehung neu erstellt wird, werden sofort die neuesten verfügbaren Daten empfangen.
Ressourcen freigeben
Sie können ein LiveData-Objekt mit dem Singleton-Muster erweitern, um Systemdienste zu verpacken, damit sie in Ihrer App freigegeben werden können. Das LiveData-Objekt stellt einmal eine Verbindung zum Systemdienst her. Alle Beobachter, die die Ressource benötigen, können 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, um einen bestimmten Datentyp zu speichern. Dies geschieht normalerweise in der Klasse ViewModel.
  2. Erstellen Sie ein Observer-Objekt, das die Methode onChanged() definiert. Damit wird gesteuert, was passiert, wenn sich die gespeicherten Daten des LiveData-Objekts ändern. Normalerweise erstellen Sie ein Observer-Objekt in einem UI-Controller, z. B. in einer Aktivität oder einem Fragment.
  3. Hängen Sie das Observer-Objekt mit der Methode observe() an das LiveData-Objekt an. Die Methode observe() nimmt ein LifecycleOwner-Objekt entgegen. Dadurch wird das Observer-Objekt dem LiveData-Objekt abonniert, sodass es über Änderungen benachrichtigt wird. Normalerweise fügen Sie das Observer-Objekt in einem UI-Controller an, z. B. in einer Aktivität oder einem Fragment.

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

Mit LiveData können UI-Controller-Beobachter Updates abonnieren. Wenn sich die vom LiveData-Objekt gespeicherten Daten ändern, wird die Benutzeroberfläche automatisch 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 es wird über eine Getter-Methode darauf zugegriffen, 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...
}

Die Daten in einem LiveData-Objekt sind anfangs nicht festgelegt.

Weitere Informationen zu den Vorteilen und zur Verwendung der Klasse ViewModel finden Sie im Leitfaden für ViewModels.

LiveData-Objekte beobachten

In den meisten Fällen ist die onCreate()-Methode einer App-Komponente der richtige Ausgangspunkt, um ein LiveData-Objekt zu beobachten. Das hat folgende Gründe:

  • So wird verhindert, dass das System redundante Aufrufe über die onResume()-Methode einer Aktivität oder eines Fragments ausführt.
  • Damit die Aktivität oder das Fragment Daten enthält, die angezeigt werden können, sobald es aktiv wird. Sobald sich eine App-Komponente im Status STARTED befindet, erhält sie den aktuellen Wert von den beobachteten LiveData-Objekten. Das geschieht nur, wenn das zu beobachtende LiveData-Objekt festgelegt wurde.

Im Allgemeinen werden über LiveData nur dann Aktualisierungen gesendet, wenn sich die Daten ändern, und nur an aktive Beobachter. Eine Ausnahme von diesem Verhalten ist, dass Beobachter auch eine Aktualisierung erhalten, wenn sie von einem inaktiven zu einem 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.

Im folgenden Codebeispiel wird gezeigt, wie Sie die Beobachtung eines LiveData-Objekts starten:

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 sofort onChanged() aufgerufen, um den in mCurrentName gespeicherten letzten Wert bereitzustellen. Wenn das LiveData-Objekt keinen Wert in mCurrentName festgelegt hat, wird onChanged() nicht aufgerufen.

LiveData-Objekte aktualisieren

LiveData bietet keine öffentlich verfügbaren Methoden zum Aktualisieren der gespeicherten Daten. Die Klasse MutableLiveData stellt die Methoden setValue(T) und postValue(T) öffentlich zur Verfügung. Sie müssen diese verwenden, wenn Sie den in einem LiveData-Objekt gespeicherten Wert bearbeiten möchten. Normalerweise wird MutableLiveData in der ViewModel verwendet. In diesem Fall stellt die 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. Im folgenden Beispiel werden alle Beobachter ausgelö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 setValue(T) im Beispiel aufgerufen wird, rufen die Beobachter ihre onChanged()-Methoden mit dem Wert John Doe auf. Im Beispiel wird eine Taste gedrückt, aber setValue() oder postValue() können aus verschiedenen Gründen aufgerufen werden, um mName zu aktualisieren, z. B. als Reaktion auf eine Netzwerkanfrage oder das Ende des Ladens einer Datenbank. In allen Fällen löst der Aufruf von setValue() oder postValue() Beobachter aus und aktualisiert die Benutzeroberfläche.

LiveData mit Google Home verwenden

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

Room generiert den gesamten erforderlichen Code, um das LiveData-Objekt zu aktualisieren, wenn eine Datenbank aktualisiert wird. Der generierte Code führt die Abfrage bei Bedarf asynchron in einem Hintergrund-Thread aus. Dieses Muster ist nützlich, um die Daten, die in einer Benutzeroberfläche angezeigt werden, mit den in einer Datenbank gespeicherten Daten zu synchronisieren. Weitere Informationen zu Room und DAOs finden Sie im Leitfaden zur Room-Persistenzbibliothek.

Koroutinen mit LiveData verwenden

LiveData unterstützt Kotlin-Coroutinen. Weitere Informationen finden Sie unter Kotlin-Coroutinen mit Android Architecture Components verwenden.

LiveData in der Architektur einer App

LiveData ist lebenszyklusorientiert und folgt dem Lebenszyklus von Entitäten wie Aktivitäten und Fragmenten. Verwende LiveData, um zwischen diesen Lebenszykluseigentümern und anderen Objekten mit einer anderen Lebensdauer zu kommunizieren, z. B. ViewModel-Objekten. Die Hauptaufgabe der ViewModel besteht darin, UI-bezogene Daten zu laden und zu verwalten. Daher eignet sie sich hervorragend zum Speichern von LiveData-Objekten. Erstellen Sie LiveData-Objekte in der ViewModel und verwenden Sie sie, um den Status für die UI-Ebene freizugeben.

Aktivitäten und Fragmente sollten keine LiveData-Instanzen enthalten, da sie Daten anzeigen und keinen Status speichern sollen. Außerdem ist es einfacher, Unit-Tests zu schreiben, wenn Aktivitäten und Fragmente keine Daten enthalten.

Es kann verlockend sein, LiveData-Objekte in der Datenebenenklasse zu verwenden. LiveData ist jedoch nicht für die Verarbeitung asynchroner Datenstreams ausgelegt. Auch wenn Sie dazu LiveData-Transformationen und MediatorLiveData verwenden können, hat dieser Ansatz Nachteile: Die Möglichkeit, Datenstreams zu kombinieren, ist sehr eingeschränkt und alle LiveData-Objekte (einschließlich der durch Transformationen erstellten) werden im Hauptthread beobachtet. Im folgenden Codebeispiel wird gezeigt, wie das Halten einer LiveData in der Repository den Haupt-Thread 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 Schichten Ihrer App verwenden müssen, können Sie Kotlin Flows verwenden und sie dann in der ViewModel mit asLiveData() in LiveData konvertieren. Weitere Informationen zur Verwendung von Kotlin Flow mit LiveData finden Sie in diesem Codelab. Bei mit Java erstellten Codebases können Sie Executors in Verbindung mit Callbacks oder RxJava verwenden.

LiveData erweitern

In LiveData gilt ein Beobachter als aktiv, wenn sich sein Lebenszyklus im Status STARTED oder RESUMED befindet. Im folgenden Beispielcode wird gezeigt, wie die Klasse LiveData erweitert wird:

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 die Aktienkursaktualisierungen über diese Methode 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 StockManager-Dienst verbunden zu bleiben.
  • Mit der Methode setValue(T) wird der Wert der LiveData-Instanz aktualisiert und alle aktiven Beobachter werden über die Änderung benachrichtigt.

Sie können die StockLiveData-Klasse 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 das LifecycleOwner, das mit der Ansicht des Fragments verknüpft ist, als erstes Argument. Dadurch wird angegeben, dass dieser Beobachter an das Lifecycle-Objekt gebunden ist, das mit dem Eigentümer verknüpft ist. Das bedeutet:

  • Wenn sich das Lifecycle-Objekt nicht in einem aktiven Zustand befindet, wird der Beobachter nicht aufgerufen, auch wenn sich der Wert ändert.
  • Nachdem das Lifecycle-Objekt gelöscht wurde, wird der Beobachter automatisch entfernt.

Da LiveData-Objekte lebenszyklusbewusst sind, können Sie sie für mehrere Aktivitäten, Fragmente und Dienste freigeben. Um das Beispiel möglichst einfach zu halten, können Sie die Klasse LiveData so 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);
    }
}

Sie können sie im Fragment 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öchten Sie den in einem LiveData-Objekt gespeicherten Wert ändern, bevor Sie ihn an die Beobachter senden. Möglicherweise müssen Sie auch eine andere LiveData-Instanz zurückgeben, die auf dem Wert einer anderen basiert. Das Paket Lifecycle enthält die Klasse Transformations mit Hilfsmethoden, die diese Szenarien unterstützen.

Transformations.map()
Wendet eine Funktion auf den im LiveData-Objekt gespeicherten Wert an und überträgt das Ergebnis nach unten.

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 map() wendet diese Funktion auf den im LiveData-Objekt gespeicherten Wert an, entpackt das Ergebnis und sendet es weiter. 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) );

Mit Transformationsmethoden können Sie Informationen über den gesamten Lebenszyklus des Beobachters hinweg übertragen. Die Transformationen werden nur berechnet, wenn ein Beobachter das zurückgegebene LiveData-Objekt beobachtet. Da die Transformationen verzögert berechnet werden, wird schleifenbezogenes Verhalten implizit weitergegeben, 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 die naive ViewModel für diese Komponente implementieren, wie im folgenden Beispielcode gezeigt:

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 sich dann jedes Mal, wenn sie getPostalCode() aufruft, vom vorherigen LiveData-Objekt abmelden und bei der neuen Instanz registrieren. Wenn die UI-Komponente neu erstellt wird, wird außerdem ein weiterer Aufruf der repository.getPostCode()-Methode ausgelöst, anstatt das Ergebnis des vorherigen Aufrufs zu verwenden.

Stattdessen können Sie die Postleitzahlensuche 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 wird das Feld postalCode als Transformation der addressInput definiert. Solange Ihrer App ein aktiver Beobachter für das Feld postalCode zugewiesen ist, wird der Wert des Felds neu berechnet und abgerufen, sobald sich postalCode ändert.addressInput

Mit diesem Mechanismus können in den unteren Ebenen der App LiveData-Objekte erstellt werden, die bei Bedarf träge berechnet werden. Ein ViewModel-Objekt kann ganz einfach Referenzen auf LiveData-Objekte abrufen und dann Transformationsregeln für sie definieren.

Neue Transformationen erstellen

Es gibt ein Dutzend spezifischer Transformationen, die in Ihrer App nützlich sein könnten, aber nicht standardmäßig zur Verfügung stehen. Wenn Sie eine eigene Transformation implementieren möchten, können Sie die Klasse MediatorLiveData verwenden. Diese überwacht andere LiveData-Objekte und verarbeitet von ihnen ausgestellte Ereignisse. MediatorLiveData überträgt seinen Status korrekt an das Quellobjekt LiveData. Weitere Informationen zu diesem Muster finden Sie in der Referenzdokumentation der Klasse Transformations.

Mehrere LiveData-Quellen zusammenführen

MediatorLiveData ist eine Unterklasse von LiveData, mit der du mehrere LiveData-Quellen zusammenführen kannst. Beobachter von MediatorLiveData-Objekten werden dann ausgelöst, wenn sich eines der ursprünglichen LiveData-Quellobjekte ändert.

Wenn Sie beispielsweise ein LiveData-Objekt in Ihrer Benutzeroberfläche 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 mit den in der Datenbank gespeicherten Daten verknüpft ist.
  • Ein LiveData-Objekt, das mit den Daten verknüpft ist, auf die über das Netzwerk zugegriffen wird.

Ihre Aktivität muss nur das Objekt MediatorLiveData beobachten, um Aktualisierungen von beiden Quellen zu erhalten. Ein detailliertes Beispiel finden Sie im Abschnitt Anhang: Netzwerkstatus freigeben des Leitfadens zur App-Architektur.

Weitere Informationen

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

Produktproben

  • Sunflower, eine Demo-App, die Best Practices mit Architekturkomponenten zeigt

Codelabs

Blogs

Videos