Android ViewModel Dan LiveData


VIEW MODEL
Secara konsep ViewModel merupakan class yang dibuat untuk menghandle logical bussines dan mempertahankan dari secara continues dalam suatu lifecycle (ex : activity / fragment)

Benefit ViewModel
- Lifecycle Aware untuk menghindari NPE ketika terjadi perubahan UI komponent pada Activity / Fragment, dimana Activity / Fragment bisa saja sudah tidak exist atau ter-destroy
- Bisa mempertahankan data ketika terjadi perubahan cofigurasi pada Activity / Fragment, misalnya rotasi layar yang mengakibatkan Activity / Fragment akan ter-create ulang.

Activity Lifecycle when screen rotated 
onPause
onStop
onSaveInstanceState
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume

Configuration changes
rotate screen
dark mode
change language

ViewModelProvider merupakan class yang berfungsi dalam menginisiasi ViewModel dan menjembatani agar ViewModel memilik kemampuan lifecycle aware

activity-ktx
implementation "androidx.activity:activity-ktx:$activity_version"
menyediakan delegasi inisiasi ViewModel dengan keyword by viewmodels()
Contoh : private val awesomeViewModel : AwesomeViewModel by viewmodels()

Shared ViewModel jika kita ingin menggunakan viewmodel pada beberapa fragment dalam 1 activity, kita bisa init 1 viewmodel yang sama yang akan digunakan pada activity dan beberapa fragment, dengan lifecycle yang terikat pada activity.
Contoh inisialisasi

Avoid android / Context
Jangan menyimpan apapun terkait class Context dalam ViewModel contohnya TextView dsb.
  1. Karena ketika terjadi perubahan configurasi misalnya rotasi screen TextView dsb pada activity akan di inisiasi ulang, sedangkan TextView dsb yang ada pada ViewModel tidak akan di inisiasi ulang yang akan mengakibatkan perbedaan instance pada TextView dsb
  2. Proses unit testing akan lebih mudah tanpa adanya class yang mewarisi class Context, sehingga unti test dapat di run hanya dengan JUnit tanpa perlu tambahan library seperti Roboelectric
LIVE DATA
Merupakan class holder data yang dapat diamati / observerable dan lifecycle friendly

Observable
An observable is an object which notifies observers about the changes in its state.
observable = dapat diamati
observers = pengamat

Istilah lainnya
publisher / emitter = pengirim / pemancar
subcriber = pelanggan

Active Lifecycle = onStart & onResume
LiveData menganggap observer berada dalam status aktif jika lifecyle-nya dalam status STARTED atau RESUMED.

setValue vs postValue

setValue():
Sets the value. If there are active observers, the value will be dispatched to them. This method must be called from the main thread.

postValue():
Posts a task to a main thread to set the given value. If you called this method multiple times before a main thread executed a posted task, only the last value would be dispatched.

Tips

1. Jangan gunakan fragment sebagai lifecycle owner, gunakanlah viewLifecycleOwner.
Karena dibeberapa kasus hanya view-nya yang ter-destroy tapi fragmentnya tidak, sehingga memungkinkan ter-init observer yang sama lebih dari 1 kali.

2. Don't exposing MutableLiveData, perlu dibuat private agar perubahan livedata hanya terjadi di viewmodel.
Perlu membuat 2 type live data 1 mutable 1 lagi imutable, lalu view observe ke imutable object agar tidak bisa melakukan perubahan state pada view (setValue / postValue).

3. Don't put observer at event handling, karena bisa ter-init lebih dari sekali