Junior
Tell me about Jetpack ViewModel.
sobes.tech AI
Answer from AI
ViewModel is a Jetpack component designed to store and manage UI-related data in a lifecycle-conscious way. Its main goal is to retain UI data during configuration changes, such as screen rotations, and to survive the lifecycle of an Activity or Fragment.
Features of ViewModel:
- Data retention: Survives configuration changes and even Activity/Fragment death, restoring data upon recreation.
- Separation of logic: Separates data preparation logic for UI from the UI itself (Activity/Fragment).
- Lifecycle-aware: Tied to the lifecycle of an Activity or Fragment.
- Memory leak prevention: Does not hold direct references to View, Lifecycle, or Activity/Fragment, preventing memory leaks.
How to use:
-
Create a class inheriting from
ViewModel.class MyViewModel : ViewModel() { private val _data = MutableLiveData<String>() val data: LiveData<String> = _data init { // Initialize data } fun fetchData() { // Data loading logic _data.value = "Loaded data" } override fun onCleared() { // Resource cleanup super.onCleared() } } -
Obtain an instance of ViewModel in an Activity or Fragment.
class MyActivity : AppCompatActivity() { private lateinit var viewModel: MyViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewModel = ViewModelProvider(this).get(MyViewModel::class.java) viewModel.data.observe(this, Observer { newData -> // Update UI }) viewModel.fetchData() } } -
Use
ViewModelProvider.Factoryto create ViewModel instances with dependencies.class MyViewModel(private val repository: MyRepository) : ViewModel() { // ... } class MyViewModelFactory(private val repository: MyRepository) : ViewModelProvider.Factory { override fun <T : ViewModel> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(MyViewModel::class.java)) { @Suppress("UNCHECKED_CAST") return MyViewModel(repository) as T } throw IllegalArgumentException("Unknown ViewModel class") } } // In Activity/Fragment // val repository = MyRepository() // Dependency injection // viewModel = ViewModelProvider(this, MyViewModelFactory(repository)).get(MyViewModel::class.java)
Comparison with onSaveInstanceState():
| Characteristic | ViewModel | onSaveInstanceState() |
|---|---|---|
| Configuration change survival | Yes | Yes (for small data volumes) |
| Process survival | No (data lost after process termination) | Yes (for small data volumes) |
| Data storage | Objects, LiveData | Bundle (primitives, Serializable, Parcelable) |
| Memory leaks | No (when used correctly) | Possible when holding references to Activity/View |
| Implementation complexity | More complex for simple scenarios | Simpler for simple scenarios |
ViewModel helps create more resilient and easily testable applications by separating UI from data processing logic.