Ringkasan LiveData Bagian dari Android Jetpack.

LiveData adalah class penyimpanan data observable. Tidak seperti observable pada umumnya, LiveData berbasis siklus proses, yang berarti observable ini mengikuti siklus proses komponen aplikasi lainnya, seperti aktivitas, fragmen, atau layanan. Basis ini memastikan LiveData hanya mengupdate pengamat komponen aplikasi yang dalam status siklus proses aktif.

LiveData menganggap pengamat, yang diwakili oleh class Observer, berstatus aktif jika siklus prosesnya berada dalam status STARTED atau RESUMED. LiveData hanya memberitahukan update kepada pengamat aktif. Pengamat nonaktif yang terdaftar untuk mengawasi objek LiveData tidak diberi tahu tentang perubahan.

Anda dapat mendaftarkan pengamat yang dipasangkan dengan objek yang mengimplementasikan antarmuka LifecycleOwner. Hubungan ini memungkinkan pengamat dihapus saat status objek Lifecycle terkait berubah menjadi DESTROYED. Ini sangat berguna untuk aktivitas dan fragmen karena keduanya dapat mengamati objek LiveData dengan aman tanpa perlu mengkhawatirkan kebocoran—aktivitas dan fragmen akan segera berhenti mengamati saat siklus proses keduanya dihancurkan.

Untuk informasi selengkapnya tentang cara penggunaan LiveData, lihat Bekerja menggunakan objek LiveData.

Keuntungan penggunaan LiveData

Penggunaan LiveData memberikan keuntungan berikut:

Memastikan UI cocok dengan status data
LiveData mengikuti pola pengamat. LiveData memberi tahu objek Observer saat data dasar berubah. Anda dapat menggabungkan kode untuk mengupdate UI di objek Observer ini. Dengan demikian, Anda tidak perlu mengupdate UI setiap kali data aplikasi berubah karena pengamat melakukannya untuk Anda.
Tidak ada kebocoran memori
Pengamat terikat pada objek Lifecycle dan mengosongkan sisa proses saat siklus proses mereka dihancurkan.
Penghentian proses tidak menyebabkan error
Jika siklus proses pengamat tidak aktif, seperti dalam kasus aktivitas di data sebelumnya, maka siklus proses pengamat tidak menerima peristiwa LiveData apa pun.
Tidak ada lagi penanganan siklus proses manual
Komponen UI hanya mengamati data yang relevan dan tidak menghentikan atau melanjutkan pengamatan. LiveData otomatis mengelola semua ini karena LiveData mengetahui terjadinya perubahan status siklus proses terkait saat melakukan pengamatan.
Data selalu diperbarui
Jika siklus proses menjadi nonaktif, siklus proses menerima data terbaru setelah aktif kembali. Misalnya, aktivitas yang berada di latar belakang menerima data terbaru setelah kembali digunakan.
Perubahan konfigurasi yang tepat
Jika suatu aktivitas atau fragmen dibuat ulang karena perubahan konfigurasi, seperti rotasi perangkat, aktivitas atau fragmen tersebut segera menerima data terbaru yang tersedia.
Berbagi resource
Anda dapat memperluas objek LiveData menggunakan pola singleton untuk menggabungkan layanan sistem sehingga dapat dibagikan di aplikasi Anda. Objek LiveData terhubung ke layanan sistem satu kali, dan setiap pengamat yang membutuhkan resource tersebut dapat langsung mengamati objek LiveData. Untuk informasi selengkapnya, lihat Memperluas LiveData.

Bekerja menggunakan objek LiveData

Ikuti langkah-langkah berikut untuk bekerja menggunakan objek LiveData:

  1. Buat instance LiveData untuk menyimpan jenis data tertentu. Ini biasanya dilakukan dalam class ViewModel.
  2. Buat objek Observer yang menentukan metode onChanged(), yang mengontrol hal yang terjadi saat data yang dibekukan milik objek LiveData berubah. Anda biasanya membuat objek Observer dalam pengontrol UI, seperti aktivitas atau fragmen.
  3. Lampirkan objek Observer ke objek LiveData menggunakan metode observe(). Metode observe() mengambil objek LifecycleOwner. Hal ini mendaftarkan objek Observer ke objek LiveData sehingga objek tersebut akan mendapatkan pemberitahuan perubahan. Anda biasanya melampirkan objek Observer dalam pengontrol UI, seperti aktivitas atau fragmen.

Saat Anda mengupdate nilai yang tersimpan dalam objek LiveData, proses update memicu semua pengamat terdaftar selama LifecycleOwner terlampir masih dalam keadaan aktif.

LiveData memungkinkan pengamat pengontrol UI untuk mendapatkan informasi update. Saat data yang disimpan objek LiveData berubah, UI otomatis merespons dengan melakukan update.

Membuat objek LiveData

LiveData adalah wrapper yang dapat digunakan dengan data apa pun, termasuk objek yang mengimplementasikan Collections, seperti List. Objek LiveData biasanya disimpan dalam objek ViewModel dan diakses melalui metode pengambil, seperti yang ditunjukkan dalam contoh berikut:

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

Awalnya, data dalam objek LiveData belum ditetapkan.

Anda dapat membaca selengkapnya tentang manfaat dan penggunaan class ViewModel di panduan ViewModel.

Mengamati objek LiveData

Dalam sebagian besar kasus, metode onCreate() komponen aplikasi adalah tempat yang tepat untuk mulai mengamati objek LiveData karena alasan berikut:

  • Untuk memastikan sistem tidak melakukan panggilan yang berlebihan dari metode onResume() aktivitas atau fragmen.
  • Untuk memastikan aktivitas atau fragmen memiliki data yang dapat ditampilkan segera setelah aktif kembali. Segera setelah berada dalam status STARTED, komponen aplikasi menerima nilai terbaru dari objek LiveData yang diamatinya. Proses ini hanya terjadi jika objek LiveData yang akan diamati telah ditetapkan.

Umumnya, LiveData meneruskan update hanya ketika data berubah, dan hanya untuk pengamat yang aktif. Pengecualian perilaku ini adalah saat pengamat juga menerima update ketika mereka berubah dari status nonaktif menjadi aktif. Selanjutnya, jika status pengamat berubah dari nonaktif menjadi aktif untuk kedua kalinya, pengamat hanya menerima update jika nilai telah berubah sejak terakhir kali status pengamat menjadi aktif.

Kode contoh berikut menunjukkan cara memulai pengamatan objek 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);
    }
}

Setelah observe() dipanggil dengan nameObserver diteruskan sebagai parameter, onChanged() segera dipanggil untuk memberikan nilai terbaru yang tersimpan di mCurrentName. Jika objek LiveData belum menetapkan nilai di mCurrentName, onChanged() tidak akan dipanggil.

Mengupdate objek LiveData

LiveData tidak memiliki metode yang tersedia untuk publik dalam memperbarui data tersimpan. Class MutableLiveData memperlihatkan metode setValue(T) dan postValue(T) secara publik, dan Anda harus menggunakan metode ini jika ingin mengedit nilai yang tersimpan di objek LiveData. Biasanya MutableLiveData digunakan dalam ViewModel dan ViewModel hanya memperlihatkan objek LiveData yang tidak dapat diubah kepada pengamat.

Setelah menyiapkan hubungan pengamat, selanjutnya Anda dapat memperbarui nilai objek LiveData seperti yang ditunjukkan oleh contoh berikut, yang memicu semua pengamat saat pengguna mengetuk suatu tombol:

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

Memanggil setValue(T) seperti dalam contoh ini mengakibatkan pengamat memanggil metode onChanged() dengan nilai John Doe. Contoh ini menunjukkan penekanan tombol, tetapi setValue() atau postValue() dapat saja dipanggil untuk mengupdate mName karena berbagai alasan, termasuk sebagai respons terhadap permintaan jaringan atau penyelesaian pemuatan database. Dalam semua kasus ini, panggilan terhadap setValue() atau postValue() memicu pengamat dan mengupdate UI.

Menggunakan LiveData dengan Room

Library persistensi Room mendukung kueri yang dapat diamati, yang menampilkan objek LiveData. Kueri observable ditulis sebagai bagian dari DAO (Objek Akses Database).

Room menghasilkan semua kode yang dibutuhkan untuk mengupdate objek LiveData saat database diupdate. Kode yang dihasilkan oleh Room menjalankan kueri secara asinkron di thread latar belakang saat diperlukan. Pola ini berguna untuk menjaga data agar yang ditampilkan di UI tetap tersinkronisasi dengan data yang tersimpan di database. Anda dapat membaca selengkapnya tentang Room dan DAO di panduan library persisten Room.

Menggunakan coroutine dengan LiveData

LiveData mencakup dukungan untuk coroutine Kotlin. Untuk informasi selengkapnya, lihat Menggunakan coroutine Kotlin dengan Komponen Arsitektur Android.

LiveData dalam arsitektur aplikasi

LiveData berbasis siklus proses, mengikuti siklus proses entity seperti aktivitas dan fragmen. Gunakan LiveData untuk berkomunikasi antara pemilik siklus proses ini dan objek lainnya dengan masa aktif yang berbeda, seperti objek ViewModel. Tanggung jawab utama ViewModel adalah memuat dan mengelola data terkait UI, yang menjadikannya kandidat terbaik untuk menyimpan objek LiveData. Buat objek LiveData di ViewModel dan gunakan untuk menampilkan status ke lapisan UI.

Aktivitas dan fragmen tidak boleh menyimpan instance LiveData, karena perannya adalah menampilkan data, bukan mempertahankan status. Selain itu, membiarkan aktivitas dan fragmen agar tidak menyimpan data akan mempermudah penulisan pengujian unit.

Anda mungkin ingin menggunakan objek LiveData di class lapisan data, tetapi LiveData tidak didesain untuk menangani aliran data asinkron. Meskipun Anda dapat menggunakan transformasi LiveData dan MediatorLiveData untuk mencapainya, pendekatan ini memiliki kelemahan, yaitu kemampuan untuk menggabungkan aliran data sangat terbatas dan semua objek LiveData (termasuk objek yang dibuat melalui transformasi) diamati pada thread utama. Kode di bawah ini adalah contoh bagaimana menyimpan LiveData dalam Repository dapat memblokir thread utama:

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

Jika Anda perlu menggunakan aliran data di lapisan lain pada aplikasi Anda, sebaiknya gunakan Alur Kotlin, lalu konversikan ke LiveData di ViewModel menggunakan asLiveData(). Pelajari lebih lanjut cara menggunakan Flow Kotlin dengan LiveData di codelab ini. Untuk codebase yang di-build dengan Java, sebaiknya gunakan Executors bersama callback atau RxJava.

Memperluas LiveData

LiveData menganggap pengamat berada dalam keadaan aktif jika siklus proses pengamat berada dalam status STARTED atau RESUMED. Kode contoh berikut mengilustrasikan cara memperluas class 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);
    }
}

Pengimplementasian pemantau harga dalam contoh ini juga menyertakan beberapa metode penting:

  • Metode onActive() dipanggil saat objek LiveData memiliki pengamat aktif. Artinya, Anda harus mulai mengamati perubahan harga saham dari metode ini.
  • Metode onInactive() dipanggil saat objek LiveData tidak memiliki pengamat aktif. Karena tidak ada pengamat yang memantau, tidak ada alasan untuk tetap terhubung dengan layanan StockManager.
  • Metode setValue(T) mengupdate nilai instance LiveData dan memberitahukan setiap pengamat aktif tentang perubahan tersebut.

Anda dapat menggunakan class StockLiveData dengan cara berikut:

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

Metode observe() meneruskan LifecycleOwner yang diatribusikan dengan tampilan fragment sebagai argumen pertama. Penerusan seperti itu menunjukkan bahwa pengamat ini terikat ke objek Lifecycle yang diatribusikan dengan pemilik, yang berarti:

  • Jika objek Lifecycle tidak dalam status aktif, pengamat tidak akan dipanggil meskipun nilai berubah.
  • Setelah objek Lifecycle dihancurkan, pengamat dihapus otomatis.

Fakta bahwa objek LiveData berbasis siklus proses berarti Anda dapat membagikan objek-objek ini di antara berbagai aktivitas, fragmen, dan layanan. Agar contoh tetap sederhana, Anda dapat mengimplementasikan class LiveData sebagai singleton dengan cara berikut:

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

Dan Anda dapat menggunakannya di fragmen dengan cara berikut:

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

Beberapa fragmen dan aktivitas dapat mengamati instance MyPriceListener. LiveData hanya terhubung ke layanan sistem jika satu atau lebih fragmen dan aktivitas terlihat dan aktif.

Mentransformasi LiveData

Anda mungkin ingin mengubah nilai yang tersimpan dalam objek LiveData sebelum mengirimkannya ke pengamat, atau Anda mungkin perlu mengirimkan instance LiveData yang berbeda berdasarkan nilai instance yang lain. Paket Lifecycle menyediakan class Transformations yang mencakup metode penunjang yang mendukung skenario ini.

Transformations.map()
Menerapkan fungsi pada nilai yang tersimpan pada objek LiveData, dan menyebarkan hasilnya ke downstream.

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()
Sama seperti map(), menerapkan fungsi pada nilai yang tersimpan dalam objek LiveData dan mengurai serta mengirimkan hasilnya ke downstream. Fungsi yang diteruskan ke switchMap() harus menampilkan objek LiveData, seperti yang ditunjukkan oleh contoh berikut:

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

Anda dapat menggunakan metode transformasi untuk membawa informasi di seluruh siklus proses pengamat. Transformasi tidak dihitung kecuali suatu pengamat sedang mengamati objek LiveData yang ditampilkan. Karena transformasi dihitung dengan lambat, perilaku terkait siklus proses secara implisit diwariskan tanpa memerlukan panggilan atau dependensi eksplisit tambahan.

Jika Anda merasa memerlukan objek Lifecycle di dalam objek ViewModel, transformasi mungkin merupakan solusi yang lebih baik. Misalnya, anggap bahwa Anda memiliki komponen UI yang menerima alamat dan menampilkan kode pos untuk alamat yang diminta tersebut. Anda dapat mengimplementasikan ViewModel naif untuk komponen ini seperti yang ditunjukkan oleh kode contoh berikut:

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

Komponen UI ini kemudian perlu membatalkan pendaftaran dari objek LiveData sebelumnya dan mendaftar ke instance baru setiap kali komponen UI memanggil getPostalCode(). Selain itu, jika komponen UI dibuat kembali, komponen UI memicu panggilan lain ke metode repository.getPostCode() dan bukan menggunakan hasil panggilan sebelumnya.

Sebagai gantinya, Anda dapat mengimplementasikan pencarian kode pos sebagai transformasi input alamat, seperti yang ditunjukkan contoh berikut:

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

Dalam hal ini, kolom postalCode ditetapkan sebagai transformasi addressInput. Selama aplikasi Anda memiliki pengamat aktif yang diatribusikan dengan kolom postalCode, nilai kolom tersebut dihitung ulang dan diambil setiap kali addressInput berubah.

Mekanisme ini memungkinkan tingkat aplikasi yang lebih rendah untuk membuat objek LiveData yang biasanya dihitung hanya jika dibutuhkan menjadi berdasarkan permintaan. Objek ViewModel dapat dengan mudah memperoleh referensi ke LiveData objek dan kemudian menentukan aturan transformasi di atas objek-objek tersebut.

Membuat transformasi baru

Ada berbagai transformasi khusus yang mungkin berguna pada aplikasi Anda, tetapi transformasi tersebut tidak disediakan secara default. Untuk mengimplementasikan transformasi sendiri, Anda dapat menggunakan class MediatorLiveData, yang memproses objek LiveData lain dan memproses peristiwa yang ditampilkan objek tersebut. MediatorLiveData dengan tepat menyebarkan statusnya ke objek LiveData sumber. Untuk mempelajari pola ini lebih lanjut, lihat dokumentasi referensi class Transformations.

Menggabungkan beberapa sumber LiveData

MediatorLiveData adalah subclass LiveData yang memungkinkan Anda menggabungkan beberapa sumber LiveData. Pengamat objek MediatorLiveData kemudian dipicu setiap kali objek sumber LiveData asli berubah.

Misalnya, jika Anda memiliki objek LiveData di UI yang dapat diupdate dari database lokal atau jaringan, Anda dapat menambahkan sumber berikut ke objek MediatorLiveData:

  • Objek LiveData yang terkait dengan data yang tersimpan dalam database.
  • Objek LiveData yang terkait dengan data yang diakses dari jaringan.

Aktivitas Anda hanya perlu mengamati objek MediatorLiveData untuk menerima update dari kedua sumber. Untuk contoh mendetail, lihat Addendum: memperlihatkan status jaringan dalam Panduan Arsitektur Aplikasi.

Referensi lainnya

Untuk mempelajari class LiveData lebih lanjut, lihat referensi berikut.

Contoh

Codelab

Blog

Video