Omówienie LiveData Część pakietu Android Jetpack.

LiveData to możliwy do obserwacji klasa posiadacza danych. W przeciwieństwie do zwykłych obserwowalnych danych LiveData uwzględnia cykl życia, co oznacza, że respektuje cykl życia innych komponentów aplikacji, takich jak działania, fragmenty czy usługi. Dzięki temu LiveData aktualizuje tylko obserwatorów komponentów aplikacji, którzy są w aktywnym cyklu życia.

LiveData uważa obserwatora reprezentowanego przez klasę Observer za aktywny, jeśli jego cykl życia ma stan STARTED lub RESUMED. LiveData powiadamia o aktualizacjach tylko aktywnych obserwatorów. Nieaktywne obserwatorzy zarejestrowane, aby obserwować obiekty LiveData, nie otrzymują powiadomień o zmianach.

Możesz zarejestrować obserwatora sparowanego z obiektem, który implementuje interfejs LifecycleOwner. Ta relacja umożliwia usunięcie obserwatora, gdy stan odpowiedniego obiektu Lifecycle zmieni się na DESTROYED. Jest to szczególnie przydatne w przypadku działań i fragmentów, ponieważ mogą one bezpiecznie obserwować obiekty LiveData i nie martwić się wyciekami – aktywności i fragmenty są natychmiast anulowane po zniszczeniu ich cyklu życia.

Więcej informacji o korzystaniu z LiveData znajdziesz w artykule Praca z obiektami LiveData.

Zalety korzystania z LiveData

Korzystanie z LiveData przynosi następujące korzyści:

Dopasowanie interfejsu użytkownika do stanu danych
LiveData podąża za wzorcem obserwatora. LiveData powiadamia o zmianach danych źródłowych w obiektach Observer. Możesz skonsolidować kod, aby zaktualizować interfejs użytkownika w tych obiektach Observer. Dzięki temu nie będzie trzeba aktualizować interfejsu przy każdej zmianie danych aplikacji, ponieważ obserwator robi to za Ciebie.
Brak wycieków pamięci
Obserwatorzy są przypisani do obiektów Lifecycle i czyszczą się po nich po zniszczeniu powiązanego z nimi cyklu życia.
Brak awarii z powodu zatrzymanych działań
Jeśli cykl życia obserwatora jest nieaktywny, na przykład w przypadku aktywności w stosie wstecznym, obserwator nie otrzyma żadnych zdarzeń LiveData.
Koniec z ręczną obsługą cyklu życia produktu
Komponenty interfejsu analizują tylko istotne dane i nie zatrzymują ani nie wznawiają obserwacji. LiveData automatycznie zarządza tym wszystkim, ponieważ podczas obserwacji wie o odpowiednich zmianach stanu cyklu życia.
Zawsze aktualne dane
Jeśli cykl życia stanie się nieaktywny, po ponownym aktywowaniu otrzyma najnowsze dane. Na przykład działanie działające w tle otrzymuje najnowsze dane zaraz po powrocie na pierwszy plan.
Prawidłowe zmiany w konfiguracji
Jeśli aktywność lub fragment zostaną odtworzone w wyniku zmiany konfiguracji, np. rotacji urządzenia, natychmiast otrzyma najnowsze dostępne dane.
Udostępnianie materiałów
Możesz rozszerzyć obiekt LiveData za pomocą wzorca singleton, aby opakować usługi systemowe tak, aby można je było udostępnić w aplikacji. Obiekt LiveData łączy się z usługą systemową raz, a każdy obserwator, który potrzebuje zasobu, może po prostu obejrzeć obiekt LiveData. Więcej informacji znajdziesz w sekcji Extend LiveData.

Praca z obiektami LiveData

Aby pracować z obiektami LiveData, wykonaj te czynności:

  1. Utwórz instancję LiveData, aby przechowywać dane określonego typu. Zwykle odbywa się to w klasie ViewModel.
  2. Utwórz obiekt Observer definiujący metodę onChanged(), która kontroluje to, co się dzieje, gdy zmieniają się dane przechowywane w obiekcie LiveData. Zwykle w kontrolerze interfejsu tworzysz obiekt Observer, np. aktywność lub fragment.
  3. Dołącz obiekt Observer do obiektu LiveData metodą observe(). Metoda observe() pobiera obiekt LifecycleOwner. Spowoduje to subskrypcję obiektu Observer w obiekcie LiveData, dzięki czemu będzie on powiadamiany o zmianach. Zwykle do kontrolera interfejsu użytkownika dołącza się obiekt Observer, np. aktywność lub fragment.

Aktualizacja wartości przechowywanej w obiekcie LiveData aktywuje wszystkich zarejestrowanych obserwatorów, o ile podłączony element LifecycleOwner jest w stanie aktywnym.

LiveData umożliwia obserwatorom kontrolera interfejsu użytkownika subskrybowanie aktualizacji. Gdy dane w obiekcie LiveData ulegną zmianie, interfejs automatycznie aktualizuje się w odpowiedzi.

Tworzenie obiektów LiveData

LiveData to kod, którego można używać z dowolnymi danymi, w tym z obiektami z implementacją Collections, takimi jak List. Obiekt LiveData jest zwykle przechowywany w obiekcie ViewModel i uzyskiwać do niego dostęp za pomocą metody pobierania, jak w tym przykładzie:

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...
}

Początkowo dane w obiekcie LiveData nie są ustawione.

Więcej informacji o zaletach i wykorzystaniu klasy ViewModel znajdziesz w przewodniku po ViewModel.

Obserwowanie obiektów LiveData

W większości przypadków metoda onCreate() w komponencie aplikacji jest właściwym miejscem do rozpoczęcia obserwacji obiektu LiveData z tych powodów:

  • Pozwala to upewnić się, że system nie wykonuje nadmiarowych wywołań z metody onResume() działania lub fragmentu.
  • Aby zapewnić, że aktywność lub fragment zawiera dane, które mogą wyświetlić się, gdy tylko staną się aktywne. Gdy tylko komponent aplikacji znajdzie się w stanie STARTED, otrzyma najnowszą wartość z obserwowanych obiektów LiveData. Dzieje się tak tylko wtedy, gdy został ustawiony obiekt LiveData do obserwacji.

Ogólnie rzecz biorąc, LiveData dostarcza aktualizacje tylko wtedy, gdy dane się zmienią, i tylko aktywnym obserwatorom. Wyjątek od tej reguły polega na tym, że obserwatorzy otrzymują też aktualizację po przejściu ze stanu nieaktywnego na aktywny. Co więcej, jeśli po raz drugi obserwator zmieni stan z nieaktywnego na aktywny, otrzyma aktualizację tylko wtedy, gdy wartość zmieniła się od czasu ostatniej aktywności.

Poniższy przykładowy kod pokazuje, jak rozpocząć obserwację obiektu LiveData:

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);
    }
}

Po wywołaniu metody observe() z parametrem nameObserver przekazywanym jako parametr obiekt onChanged() jest natychmiast wywoływany, podając najnowszą wartość zapisaną w obiekcie mCurrentName. Jeśli obiekt LiveData nie ustawił wartości w mCurrentName, właściwość onChanged() nie jest wywoływana.

Aktualizowanie obiektów LiveData

LiveData nie ma publicznie dostępnych metod aktualizowania przechowywanych danych. Klasa MutableLiveData ujawnia metody setValue(T) i postValue(T) publicznie. Musisz ich użyć, jeśli chcesz edytować wartość zapisaną w obiekcie LiveData. Zwykle używany jest w ViewModel element MutableLiveData, a potem ViewModel udostępnia obserwatorom tylko stałe obiekty LiveData.

Po skonfigurowaniu relacji obserwatora możesz zaktualizować wartość obiektu LiveData (jak pokazano w tym przykładzie), który będzie wywoływać wszystkich obserwatorów po kliknięciu przycisku:

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);
    }
});

Wywołanie setValue(T) w tym przykładzie sprawia, że obserwatorzy wywołują swoje metody onChanged() z wartością John Doe. Przykład przedstawia naciśnięcie przycisku, ale funkcja setValue() lub postValue() może być wywoływana w celu zaktualizowania mName z różnych powodów, np. w odpowiedzi na żądanie sieciowe lub wczytanie bazy danych. We wszystkich przypadkach wywołanie setValue() lub postValue() aktywuje obserwacje i aktualizuje interfejs.

Używanie LiveData z pokojem

Biblioteka trwałości Room obsługuje obserwowalne zapytania, które zwracają obiekty LiveData. Dostrzegalne zapytania są zapisywane w ramach obiektu Database Access Object (DAO).

Room generuje cały kod niezbędny do aktualizacji obiektu LiveData po aktualizacji bazy danych. W razie potrzeby wygenerowany kod uruchamia zapytanie asynchronicznie w wątku w tle. Przydaje się on do utrzymywania synchronizacji danych wyświetlanych w interfejsie z danymi przechowywanymi w bazie danych. Więcej informacji o salach i atrybucji DAO znajdziesz w przewodniku po bibliotece trwałej w salach.

Używanie współprogramów z LiveData

LiveData zapewnia obsługę współprogramów Kotlin. Więcej informacji znajdziesz w artykule o używaniu współprogramów Kotlin z komponentami architektury Androida.

LiveData w architekturze aplikacji

LiveData uwzględnia cykl życia i odpowiada cyklowi życia encji, takich jak działania i fragmenty. LiveData umożliwia komunikację między tymi właścicielami cyklu życia a innymi obiektami o innym czasie trwania, takimi jak obiekty ViewModel. Głównym zadaniem instancji ViewModel jest wczytywanie danych związanych z interfejsem i zarządzanie nimi, dzięki czemu doskonale nadaje się do przechowywania obiektów LiveData. Utwórz obiekty LiveData w ViewModel i używaj ich do ujawniania stanu w warstwie interfejsu.

Aktywności i fragmenty nie powinny zatrzymywać instancji LiveData, ponieważ ich rola to wyświetlanie danych, a nie blokowanie stanu. Poza tym uwolnienie działań i fragmentów do przechowywania danych ułatwia pisanie testów jednostkowych.

Działanie obiektów LiveData w klasie warstwy danych może być kuszące, ale funkcja LiveData nie jest przeznaczona do obsługi asynchronicznych strumieni danych. Mimo że możesz to osiągnąć za pomocą przekształceń LiveData i MediatorLiveData, to podejście ma wady: możliwość łączenia strumieni danych jest bardzo ograniczona i wszystkie obiekty LiveData (w tym utworzone za pomocą przekształceń) są obserwowane w wątku głównym. Poniższy kod to przykład tego, jak przytrzymanie LiveData w Repository może zablokować wątek główny:

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()));
    }
}

Jeśli chcesz używać strumieni danych w innych warstwach aplikacji, rozważ użycie Kotlin Flows, a potem przekonwertowanie ich na LiveData w ViewModel za pomocą asLiveData(). Więcej informacji o korzystaniu z narzędzia Kotlin Flow w połączeniu z elementem LiveData znajdziesz w tym ćwiczeniu w programie. W przypadku baz kodu utworzonych w Javie rozważ użycie wykonawców w połączeniu z wywołaniami zwrotnymi lub RxJava.

Rozszerzanie danych LiveData

LiveData uznaje obserwatora w stanie aktywny, jeśli jego cykl życia znajduje się w stanie STARTED lub RESUMED. W tym przykładowym kodzie widać, jak rozszerzyć klasę LiveData:

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);
    }
}

Implementacja odbiornika cen w tym przykładzie obejmuje następujące ważne metody:

  • Metoda onActive() jest wywoływana, gdy obiekt LiveData ma aktywnego obserwatora. Oznacza to, że musisz zacząć obserwować zmiany cen akcji za pomocą tej metody.
  • Metoda onInactive() jest wywoływana, gdy obiekt LiveData nie ma aktywnych obserwatorów. Żaden obserwator nie słucha, więc nie ma powodu, żeby pozostawać w kontakcie z usługą StockManager.
  • Metoda setValue(T) aktualizuje wartość instancji LiveData i powiadamia o zmianie wszystkie aktywne obserwatorzy.

Z zajęć StockLiveData możesz korzystać w następujący sposób:

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.
        });
    }
}

Metoda observe() przekazuje jako pierwszy argument parametr LifecycleOwner powiązany z widokiem fragmentu. Oznacza to, że ten obserwator jest powiązany z obiektem Lifecycle powiązanym z właścicielem, co oznacza:

  • Jeśli obiekt Lifecycle nie jest w stanie aktywnym, obserwator nie zostanie wywołany, nawet jeśli wartość się zmieni.
  • Po zniszczeniu obiektu Lifecycle obserwator jest automatycznie usuwany.

Fakt, że obiekty LiveData są świadome cyklu życia, oznacza, że można je współdzielić między wieloma aktywnościami, fragmentami i usługami. Aby przykład był prosty, możesz wdrożyć klasę LiveData jako singleton w ten sposób:

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);
    }
}

Można go użyć we fragmencie w następujący sposób:

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.
        });
    }
}

Wiele fragmentów i działań może obserwować wystąpienie MyPriceListener. LiveData łączy się z usługą systemową tylko wtedy, gdy co najmniej jedna z nich jest widoczna i aktywna.

Przekształć LiveData

Przed wysłaniem go do obserwatorów możesz zmodyfikować wartość przechowywanej w obiekcie LiveData. Może być też konieczne zwrócenie innej instancji LiveData w zależności od wartości innej instancji. Pakiet Lifecycle zawiera klasę Transformations, która obejmuje metody pomocnicze obsługujące takie scenariusze.

Transformations.map()
Stosuje funkcję do wartości zapisanej w obiekcie LiveData i rozpowszechnia wynik w dół.

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()
Podobnie jak map() stosuje funkcję do wartości przechowywanej w obiekcie LiveData oraz wyodrębnia i wysyła wynik w dół. Funkcja przekazana do switchMap() musi zwracać obiekt LiveData, tak jak w tym przykładzie:

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

Możesz stosować metody przekształcania, aby przenosić informacje przez cały cykl życia obserwatora. Przekształcenia nie są obliczane, dopóki obserwator nie obserwuje zwróconego obiektu LiveData. Przekształcenia są obliczane w sposób leniwy, dlatego działania związane z cyklem życia są niejawnie przekazywane i nie wymagają dodatkowych jawnych wywołań ani zależności.

Jeśli uważasz, że potrzebujesz obiektu Lifecycle w obiekcie ViewModel, lepszym rozwiązaniem będzie przekształcenie. Załóżmy na przykład, że masz komponent interfejsu, który akceptuje adres i zwraca kod pocztowy tego adresu. Możesz zaimplementować naiwną ViewModel dla tego komponentu w sposób przedstawiony w tym przykładowym kodzie:

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);
    }
}

Następnie komponent interfejsu musi wyrejestrować się z poprzedniego obiektu LiveData i zarejestrować w nowej instancji za każdym razem, gdy wywołuje metodę getPostalCode(). Poza tym, jeśli komponent interfejsu zostanie odtworzony, aktywuje kolejne wywołanie metody repository.getPostCode(), zamiast korzystać z wyniku poprzedniego wywołania.

Zamiast tego możesz zastosować wyszukiwanie kodu pocztowego jako przekształcenie wpisanego adresu, jak w tym przykładzie:

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);
  }
}

W tym przypadku pole postalCode jest zdefiniowane jako przekształcenie kolumny addressInput. Jeśli w aplikacji ma aktywnego obserwatora powiązanego z polem postalCode, wartość tego pola jest przeliczana i pobierana po każdej zmianie parametru addressInput.

Ten mechanizm umożliwia użytkownikom na niższych poziomach aplikacji tworzenie obiektów LiveData, które są leniwie obliczone na żądanie. Obiekt ViewModel może łatwo uzyskiwać odwołania do obiektów LiveData, a następnie określać na ich podstawie reguły przekształcania.

Tworzenie nowych przekształceń

Istnieje kilkanaście różnych przekształceń, które mogą być przydatne w Twojej aplikacji, ale nie są one dostępne domyślnie. Aby wdrożyć własne przekształcenie, możesz użyć klasy MediatorLiveData, która nasłuchuje innych obiektów LiveData i przetwarza generowane przez nie zdarzenia. MediatorLiveData prawidłowo przekazuje swój stan do źródłowego obiektu LiveData. Więcej informacji o tym wzorcu znajdziesz w dokumentacji klasy Transformations.

Scal wiele źródeł LiveData

MediatorLiveData to podklasa klasy LiveData, która umożliwia scalanie wielu źródeł LiveData. Obserwatorzy obiektów MediatorLiveData są wyzwalane po każdej zmianie oryginalnego obiektu źródła LiveData.

Jeśli na przykład masz w interfejsie obiekt LiveData, który można zaktualizować z poziomu lokalnej bazy danych lub sieci, możesz dodać do obiektu MediatorLiveData te źródła:

  • Obiekt LiveData powiązany z danymi przechowywanymi w bazie danych.
  • Obiekt LiveData powiązany z danymi, do których uzyskuje się dostęp z sieci.

Twoja aktywność musi tylko obserwować obiekt MediatorLiveData, aby otrzymywać aktualizacje z obu źródeł. Szczegółowy przykład znajdziesz w sekcji Addendum: exposing network status (Ujawnianie stanu sieci) Przewodnika po architekturze aplikacji.

Dodatkowe materiały

Więcej informacji o klasie LiveData znajdziesz w materiałach poniżej.

Próbki

Ćwiczenia z programowania

Blogi

Filmy