Omówienie LiveData   Należy do Android Jetpack.

LiveData to obserwowalna klasa uchwytu danych. W odróżnieniu od zwykłego observable obiekt LiveData jest świadomy cyklu życia, co oznacza, że respektuje cykl życia innych komponentów aplikacji, takich jak aktywności, fragmenty czy usługi. Dzięki temu LiveData aktualizuje tylko obserwatorów komponentów aplikacji, które są w aktywności.

LiveData uznaje obserwatora, który jest reprezentowany przez klasę Observer, za aktywny, jeśli jego cykl życia jest w stanie STARTED lub RESUMED. LiveData powiadamia o aktualizacjach tylko aktywnych obserwatorów. Nieaktywne obserwatorów zarejestrowane do obserwowania obiektów LiveData nie są powiadamiane o zmianach.

Możesz zarejestrować obserwatora sparowanego z obiektem, który implementuje interfejs LifecycleOwner. Ta relacja umożliwia usunięcie obserwatora, gdy stan odpowiadającego mu obiektu Lifecycle zmieni się na DESTROYED. Jest to szczególnie przydatne w przypadku aktywności i fragmentów, ponieważ mogą one bezpiecznie obserwować obiekty LiveData bez obaw o wycieki. Aktywności i fragmenty są natychmiast odsubskrybowane po zakończeniu ich cyklu życia.

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

Zalety korzystania z LiveData

Korzystanie z LiveData ma te zalety:

Sprawdzanie, czy interfejs użytkownika jest zgodny ze stanem danych
LiveData działa zgodnie ze wzorcem obserwatora. Usługa LiveData wysyła powiadomienia do obiektów Observer, gdy dane źródłowe ulegną zmianie. Aby zaktualizować interfejs za pomocą tych obiektów Observer, możesz scalić kod. Dzięki temu nie musisz aktualizować interfejsu za każdym razem, gdy zmieniają się dane aplikacji, ponieważ obserwator robi to za Ciebie.
Brak wycieków pamięci
Obserwatory są powiązani z obiektami Lifecycle i usuwają po sobie, gdy ich powiązany cykl życia zostanie zniszczony.
Brak awarii spowodowanych zatrzymanymi działaniami
Jeśli cykl życia obserwatora jest nieaktywny, np. w przypadku aktywności w grupie wstecznej, nie otrzymuje on żadnych zdarzeń LiveData.
Bez ręcznego zarządzania cyklem życia
Komponenty interfejsu tylko obserwują odpowiednie dane i nie przerywają ani nie wznawiają obserwacji. LiveData automatycznie zarządza wszystkimi tymi funkcjami, ponieważ podczas obserwacji jest świadoma odpowiednich zmian stanu cyklu życia.
Zawsze aktualne dane
Jeśli cykl życia stanie się nieaktywny, po ponownym stanie się aktywnym otrzyma najnowsze dane. Na przykład aktywność, która była wykonywana w tle, otrzymuje najnowsze dane zaraz po tym, jak wraca na pierwszy plan.
Właściwe zmiany konfiguracji
Jeśli aktywność lub fragment zostanie utworzony ponownie z powodu zmiany konfiguracji, np. obracania urządzenia, natychmiast otrzyma najnowsze dostępne dane.
Udostępnianie zasobów
Możesz rozszerzyć obiekt LiveData, używając wzorca singleton, aby owijać usługi systemowe, tak aby można było je udostępniać w aplikacji. Obiekt LiveData łączy się z usługą systemową tylko raz, a następnie każdy obserwator, który potrzebuje zasobu, może obserwować obiekt LiveData. Więcej informacji znajdziesz w artykule Rozszerzanie danych LiveData.

Praca z obiektmi LiveData

Aby pracować z obiektmi LiveData:

  1. Utwórz instancję LiveData, aby przechowywać określony typ danych. Zwykle odbywa się to w ramach klasy ViewModel.
  2. Utwórz obiekt Observer, który definiuje metodę onChanged(), która określa, co się stanie, gdy zmienią się dane przechowywane w obiekcie LiveData. Obiekt Observer zwykle tworzysz w kontrolerze interfejsu użytkownika, takim jak aktywność lub fragment.
  3. Za pomocą metody observe() dołącz obiekt Observer do obiektu LiveData. Metoda observe() przyjmuje obiekt LifecycleOwner. Dzięki temu obiekt Observer subskrybuje obiekt LiveData, aby otrzymywać powiadomienia o zmianach. Obiekt Observer zwykle dołączasz w kontrolerze interfejsu użytkownika, takim jak aktywność lub fragment.

Gdy zaktualizujesz wartość przechowywaną w obiekcie LiveData, powoduje to wywołanie wszystkich zarejestrowanych obserwatorów, o ile dołączony obiekt LifecycleOwner jest w stanie aktywnym.

LiveData umożliwia obserwatorom kontrolera interfejsu subskrybowanie aktualizacji. Gdy dane przechowywane przez obiekt LiveData ulegną zmianie, interfejs użytkownika zostanie automatycznie zaktualizowany.

Tworzenie obiektów LiveData

LiveData to obiekt opakowujący, który może być używany z dowolnymi danymi, w tym z obiektami, które implementują interfejs Collections, np. List. Obiekt LiveData jest zwykle przechowywany w obiekcie ViewModeli jest dostępny za pomocą metody gettera, jak pokazano 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 użyciu klasy ViewModel znajdziesz w przewodniku ViewModel.

Obserwowanie obiektów LiveData

W większości przypadków metoda onCreate() komponentu aplikacji jest odpowiednim miejscem na rozpoczęcie obserwowania obiektu LiveData z tych powodów:

  • Aby mieć pewność, że system nie wykonuje zbędnych wywołań z metody onResume() aktywności lub fragmentu.
  • Aby mieć pewność, że aktywność lub fragment będzie mieć dane, które może wyświetlić, gdy stanie się aktywny. Gdy tylko komponent aplikacji znajdzie się w stanie STARTED, odbiera najnowszą wartość z obserwowanych obiektów LiveData. Dzieje się tak tylko wtedy, gdy ustawiono obiekt LiveData, który ma być obserwowany.

Zazwyczaj LiveData dostarcza aktualizacje tylko wtedy, gdy zmieniają się dane, i tylko aktywnym obserwatorom. Wyjątkiem od tej zasady jest to, że obserwatorzy również otrzymują aktualizację, gdy stan ich konta zmieni się z nieaktywne na aktywne. Ponadto jeśli obserwator zmieni stan z nieaktywnego na aktywny po raz drugi, otrzyma aktualizację tylko wtedy, gdy wartość zmieniła się od ostatniego stanu aktywnego.

Poniższy przykładowy kod pokazuje, jak rozpocząć obserwowanie 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 funkcji observe() z parametrem nameObserver natychmiast wywoływana jest funkcja onChanged(), która przekazuje najnowszą wartość przechowywaną w tablicy mCurrentName. Jeśli obiekt LiveData nie ma ustawionej wartości w elementach mCurrentName, funkcja onChanged() nie jest wywoływana.

Aktualizowanie obiektów LiveData

Usługa LiveData nie udostępnia publicznie metod aktualizowania przechowywanych danych. Klasa MutableLiveData udostępnia publicznie metody setValue(T) i postValue(T). Musisz ich używać, jeśli chcesz edytować wartość przechowywaną w obiekcie LiveData. Zazwyczaj w sekcji ViewModel używana jest funkcja MutableLiveData, a obiekt ViewModel udostępnia obserwatorom tylko niezmienne obiekty LiveData.

Po skonfigurowaniu relacji obserwatora możesz zaktualizować wartość obiektu LiveData, jak pokazano w następującym przykładzie, który uruchamia wszystkich obserwatorów, gdy użytkownik kliknie przycisk:

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 powoduje, że obserwatorzy wywołują metody onChanged() z wartością John Doe. Przykład pokazuje naciśnięcie przycisku, ale funkcja setValue() lub postValue() może zostać wywołana w celu zaktualizowania mName z różnych powodów, np. w odpowiedzi na żądanie sieci lub po zakończeniu wczytywania bazy danych. We wszystkich przypadkach wywołanie funkcji setValue() lub postValue() powoduje uruchomienie obserwatorów i zaktualizowanie interfejsu użytkownika.

Korzystanie z LiveData w Room

Biblioteka trwałości danych Room obsługuje zapytania obserwowalne, które zwracają obiekty LiveData. Zapytania obserwowalne są pisane jako część obiektu dostępu do bazy danych (DAO).

Gdy aktualizujesz bazę danych, Room generuje cały kod potrzebny do zaktualizowania obiektu LiveData. Wygenerowany kod w razie potrzeby wykonuje zapytanie asynchronicznie na wątku w tle. Ten wzorzec jest przydatny do synchronizowania danych wyświetlanych w interfejsie z danymi zapisanymi w bazie danych. Więcej informacji o Room i DAO znajdziesz w przewodniku po bibliotece trwałości danych Room.

Korzystanie z coroutines w LiveData

LiveData obsługuje coroutines w Kotlinie. Więcej informacji znajdziesz w artykule Używanie współbieżnych funkcji w Kotlinie z Android Architecture Components.

LiveData w architekturze aplikacji

LiveData uwzględnia cykl życia, podążając za cyklem życia takich elementów jak aktywności i fragmenty. Użyj obiektu LiveData, aby umożliwić komunikację między właścicielami cyklu życia a innymi obiektami o innej długości życia, takimi jak obiekty ViewModel. Głównym zadaniem obiektu ViewModel jest wczytywanie danych związanych z interfejsem użytkownika i zarządzanie nimi, co czyni go idealnym kandydatem do przechowywania obiektów LiveData. Utwórz obiekty LiveData w komponencie ViewModel i użyj ich do udostępniania stanu warstwie interfejsu użytkownika.

Aktywności i fragmenty nie powinny przechowywać instancji LiveData, ponieważ ich zadaniem jest wyświetlanie danych, a nie przechowywanie stanu. Poza tym brak danych w akcjach i fragmentach ułatwia tworzenie testów jednostkowych.

Możesz mieć ochotę na pracę z obiektmi LiveData w klasie warstwy danych, ale LiveData nie jest przeznaczony do obsługi asynchronicznych strumieni danych. Mimo że do tego celu możesz użyć przekształceń LiveData i funkcji MediatorLiveData, takie podejście ma pewne wady: możliwość łączenia strumieni danych jest bardzo ograniczona, a wszystkie obiekty LiveData (w tym te utworzone przez przekształcenia) są obserwowane w głównym wątku. Poniższy kod pokazuje, jak zablokowanie LiveData w pętli Repository może blokować główny wątek:

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 ich konwersję na LiveDataViewModel za pomocą asLiveData(). Więcej informacji o używaniu Kotlina FlowLiveData znajdziesz w tym Codelab. W przypadku baz kodu utworzonych w języku Java rozważ użycie wykonawców w połączeniu z wywołaniami zwrotnymi lub RxJava.

Rozszerzanie danych na żywo

Z punktu widzenia usługi LiveData obserwator jest aktywny, jeśli jego cykl życia jest w stanie STARTED lub RESUMED. Poniższy przykładowy kod pokazuje, 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 te ważne metody:

  • Metoda onActive() jest wywoływana, gdy obiekt LiveData ma aktywnego obserwatora. Oznacza to, że musisz zacząć obserwować aktualizacje cen akcji z tej metody.
  • Metoda onInactive() jest wywoływana, gdy obiekt LiveData nie ma aktywnych obserwatorów. Ponieważ nie ma obserwatorów, nie ma powodu, aby pozostać w połączeniu z usługą StockManager.
  • Metoda setValue(T) aktualizuje wartość instancji LiveData i powiadamia o tej zmianie wszystkich aktywnych obserwatorów.

Klasę StockLiveData możesz używać w taki 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 LifecycleOwnerpowiązany z widokiem fragmentu. Oznacza to, że ten obserwator jest powiązany z obiektem Lifecycle powiązanym z właścicielem, co oznacza, że:

  • Jeśli obiekt Lifecycle nie jest aktywny, obserwator nie jest wywoływany, nawet jeśli wartość się zmieni.
  • Po zniszczeniu obiektu Lifecycle obserwator zostanie automatycznie usunięty.

Obiekty LiveData są świadome cyklu życia, co oznacza, że możesz je udostępniać między wieloma aktywnościami, fragmentami i usługami. Aby przykład był prostszy, klasę LiveData możesz zaimplementować jako pojedynczy obiekt 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żesz go użyć w fragmentzie w ten 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.
        });
    }
}

Fragmenty i aktywności mogą obserwować instancję MyPriceListener. LiveData łączy się z usługą systemową tylko wtedy, gdy co najmniej 1 z nich jest widoczna i aktywna.

Przekształcanie danych LiveData

Możesz wprowadzić zmiany w wartości przechowywanej w obiekcie LiveData przed wysłaniem go do obserwatorów. Może też być konieczne zwrócenie innego wystąpienia obiektu LiveData na podstawie wartości innego. Pakiet Lifecycle udostępnia klasę Transformations, która zawiera metody pomocnicze obsługujące te scenariusze.

Transformations.map()
Stosuje funkcję do wartości przechowywanej w obiekcie LiveData, a potem przekazuje wynik do dalszych elementów.

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, a następnie odwija i wysyła wynik do dalszego przetwarzania. Funkcja przekazana do switchMap() musi zwracać obiekt LiveData, jak pokazano 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) );

Metody przekształcania umożliwiają przenoszenie informacji w cyklu życia obserwatora. Przekształcenia nie są obliczane, chyba że obserwator obserwuje zwrócony obiekt LiveData. Przekształcenia są obliczane płynnie, więc zachowanie związane z cyklem życia jest przekazywane do podklas w sposób domyślny bez konieczności korzystania z dodatkowych wywołań ani zależności.

Jeśli uważasz, że obiekt Lifecycle powinien znajdować się w obiekcie ViewModel, prawdopodobnie lepszym rozwiązaniem będzie użycie transformacji. Załóżmy na przykład, że masz komponent interfejsu użytkownika, który przyjmuje adres i zwraca kod pocztowy tego adresu. W przypadku tego komponentu możesz zastosować prostą funkcję ViewModel, jak 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);
    }
}

Komponent UI musi wtedy anulować rejestrację poprzedniego obiektu LiveData i zarejestrować się w nowym wystąpieniu za każdym razem, gdy wywołuje funkcję getPostalCode(). Ponadto jeśli komponent interfejsu użytkownika zostanie utworzony ponownie, spowoduje to wywołanie metody repository.getPostCode(), a nie wykorzystanie wyniku poprzedniego wywołania.

Zamiast tego możesz zastosować wyszukiwanie kodu pocztowego jako przekształcenie danych wejściowych adresu, jak pokazano 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 pola addressInput. Dopóki Twoja aplikacja ma aktywnego obserwatora powiązanego z polem postalCode, jego wartość jest ponownie obliczana i pobierana za każdym razem, gdy zmienia się wartość pola addressInput.

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

Tworzenie nowych przekształceń

Istnieje kilkanaście różnych transformacji, które mogą być przydatne w aplikacji, ale nie są one dostępne domyślnie. Aby zaimplementować własną transformację, możesz użyć klasy MediatorLiveData, która nasłuchuje innych obiektów LiveData i przetwarza emitowane przez nie zdarzenia. MediatorLiveData prawidłowo rozpowszechnia swój stan do obiektu źródłowego LiveData. Więcej informacji o tym wzorze znajdziesz w dokumentacji referencyjnej klasy Transformations.

Scalanie kilku źródeł LiveData

MediatorLiveData to podklasa klasy LiveData, która umożliwia scalanie wielu źródeł LiveData. Obserwatory obiektów MediatorLiveData są następnie uruchamiane, gdy nastąpi jakakolwiek zmiana w pierwotnych obiektach źródłowych LiveData.

Jeśli na przykład masz w interfejsie obiekt LiveData, który można aktualizować z bazy danych lokalnej 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 uzyskanymi z sieci.

Aby otrzymywać aktualizacje z obu źródeł, Twoja aktywność musi tylko obserwować obiekt MediatorLiveData. Szczegółowy przykład znajdziesz w sekcji Załącznik: wyświetlanie stanu sieciprzewodniku Architektura aplikacji.

Dodatkowe materiały

Więcej informacji o klasie LiveData znajdziesz w tych materiałach.

Próbki

  • Sunflower, aplikacja demonstracyjna prezentująca sprawdzone metody dotyczące komponentów architektury

Ćwiczenia z programowania

Blogi

Filmy