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 diesenObserver
-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. DasLiveData
-Objekt stellt einmal eine Verbindung zum Systemdienst her. Alle Beobachter, die die Ressource benötigen, können dann einfach dasLiveData
-Objekt beobachten. Weitere Informationen finden Sie unter LiveData erweitern.
Mit LiveData-Objekten arbeiten
So arbeiten Sie mit LiveData
-Objekten:
- Erstellen Sie eine Instanz von
LiveData
, um einen bestimmten Datentyp zu speichern. Dies geschieht normalerweise in der KlasseViewModel
. - Erstellen Sie ein
Observer
-Objekt, das die MethodeonChanged()
definiert. Damit wird gesteuert, was passiert, wenn sich die gespeicherten Daten desLiveData
-Objekts ändern. Normalerweise erstellen Sie einObserver
-Objekt in einem UI-Controller, z. B. in einer Aktivität oder einem Fragment. Hängen Sie das
Observer
-Objekt mit der Methodeobserve()
an dasLiveData
-Objekt an. Die Methodeobserve()
nimmt einLifecycleOwner
-Objekt entgegen. Dadurch wird dasObserver
-Objekt demLiveData
-Objekt abonniert, sodass es über Änderungen benachrichtigt wird. Normalerweise fügen Sie dasObserver
-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 beobachtetenLiveData
-Objekten. Das geschieht nur, wenn das zu beobachtendeLiveData
-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 dasLiveData
-Objekt einen aktiven Beobachter hat. Das bedeutet, dass Sie die Aktienkursaktualisierungen über diese Methode beobachten müssen. - Die Methode
onInactive()
wird aufgerufen, wenn dasLiveData
-Objekt keine aktiven Beobachter hat. Da keine Beobachter zuhören, gibt es keinen Grund, mit demStockManager
-Dienst verbunden zu bleiben. - Mit der Methode
setValue(T)
wird der Wert derLiveData
-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 imLiveData
-Objekt gespeicherten Wert an, entpackt das Ergebnis und sendet es weiter. Die answitchMap()
übergebene Funktion muss einLiveData
-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
- Android Room with a View (Java) (Kotlin)
- Erweiterte Coroutinen mit Kotlin Flow und LiveData
Blogs
- ViewModels and LiveData: Patterns + AntiPatterns
- LiveData über das ViewModel hinaus – Reaktive Muster mit Transformationen und MediatorLiveData
- LiveData mit SnackBar, Navigation und anderen Ereignissen (SingleLiveEvent-Fall)
Videos
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Kotlin-Coroutinen mit sitzungsabhängigen Komponenten verwenden
- Lebenszyklen mit lebenszyklusorientierten Komponenten verwalten
- Implementierung der Seitennavigation testen