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 objekObserver
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 pengamat diakhiri. - 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 kembali 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. ObjekLiveData
terhubung ke layanan sistem satu kali, dan setiap pengamat yang membutuhkan resource tersebut dapat langsung mengamati objekLiveData
. Untuk informasi selengkapnya, lihat Memperluas LiveData.
Bekerja menggunakan objek LiveData
Ikuti langkah-langkah berikut untuk bekerja
menggunakan objek LiveData
:
- Buat instance
LiveData
untuk menyimpan jenis data tertentu. Ini biasanya dilakukan dalam classViewModel
. - Buat objek
Observer
yang menentukan metodeonChanged()
, yang mengontrol hal yang terjadi saat data yang dibekukan milik objekLiveData
berubah. Anda biasanya membuat objekObserver
dalam pengontrol UI, seperti aktivitas atau fragmen. Lampirkan objek
Observer
ke objekLiveData
menggunakan metodeobserve()
. Metodeobserve()
mengambil objekLifecycleOwner
. Hal ini mendaftarkan objekObserver
ke objekLiveData
sehingga objek tersebut akan mendapatkan pemberitahuan perubahan. Anda biasanya melampirkan objekObserver
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 objekLiveData
yang diamatinya. Proses ini hanya terjadi jika objekLiveData
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 dibangun 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 objekLiveData
memiliki pengamat aktif. Artinya, Anda harus mulai mengamati perubahan harga saham dari metode ini. - Metode
onInactive()
dipanggil saat objekLiveData
tidak memiliki pengamat aktif. Karena tidak ada pengamat yang memantau, tidak ada alasan untuk tetap terhubung dengan layananStockManager
. - Metode
setValue(T)
mengupdate nilai instanceLiveData
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 objekLiveData
dan mengurai serta mengirimkan hasilnya ke downstream. Fungsi yang diteruskan keswitchMap()
harus menampilkan objekLiveData
, 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
- Sunflower, yakni aplikasi demo yang menunjukkan praktik terbaik dengan Komponen Arsitektur
Codelab
- Android Room dengan View (Java) (Kotlin)
- Mempelajari coroutine lanjutan dengan Flow dan LiveData Kotlin
Blog
- ViewModel dan LiveData: Pola + Anti-Pola
- LiveData di luar ViewModel — Pola reaktif menggunakan Transformasi dan MediatorLiveData
- LiveData dengan SnackBar, Navigation, dan peristiwa lainnya (kasus SingleLiveEvent)
Video
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Menggunakan coroutine Kotlin dengan komponen yang mendukung siklus proses
- Menangani Siklus Proses dengan Komponen Berbasis Siklus Proses
- Menguji implementasi Paging