Sobes.tech
Junior

Opowiedz o Jetpack ViewModel.

sobes.tech AI

Odpowiedź od AI

ViewModel to komponent Jetpack zaprojektowany do przechowywania i zarządzania danymi w sposób powiązany z interfejsem użytkownika. Jego głównym celem jest zachowanie danych UI podczas zmian konfiguracji, takich jak obrót ekranu, oraz przetrwanie cyklu życia Activity lub Fragment.

Cechy ViewModel:

  • Przechowywanie danych: Przetrwa zmiany konfiguracji, a nawet śmierć Activity/Fragment, przywracając dane podczas ponownego tworzenia.
  • Oddzielenie logiki: Oddziela logikę przygotowania danych dla UI od samego UI (Activity/Fragment).
  • Powiązanie z cyklem życia: Jest powiązany z cyklem życia Activity lub Fragment.
  • Zapobieganie wyciekom pamięci: Nie utrzymuje bezpośrednich odniesień do View, Lifecycle czy Activity/Fragment, co zapobiega wyciekom.

Jak używać:

  1. Utwórz klasę dziedziczącą po ViewModel.

    class MyViewModel : ViewModel() {
        private val _data = MutableLiveData<String>()
        val data: LiveData<String> = _data
    
        init {
            // Inicjalizacja danych
        }
    
        fun fetchData() {
            // Logika ładowania danych
            _data.value = "Załadowane dane"
        }
    
        override fun onCleared() {
            // Czyszczenie zasobów
            super.onCleared()
        }
    }
    
  2. Uzyskaj instancję ViewModel w Activity lub 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 ->
                // Aktualizacja UI
            })
    
            viewModel.fetchData()
        }
    }
    
  3. Użyj ViewModelProvider.Factory, aby tworzyć instancje ViewModel z zależnościami.

    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("Nieznana klasa ViewModel")
        }
    }
    
    // W Activity/Fragment
    // val repository = MyRepository() // Wstrzykiwanie zależności
    // viewModel = ViewModelProvider(this, MyViewModelFactory(repository)).get(MyViewModel::class.java)
    

Porównanie z onSaveInstanceState():

Cecha ViewModel onSaveInstanceState()
Przetrwanie zmian konfiguracji Tak Tak (dla małych ilości danych)
Przetrwanie procesu Nie (dane tracą się po zniszczeniu procesu) Tak (dla małych ilości danych)
Przechowywanie danych Obiekty, LiveData Bundle (prymitywy, Serializable, Parcelable)
Wycieki pamięci Nie (jeśli używany poprawnie) Możliwe, jeśli utrzymuje się odniesienia do Activity/View
Złożoność implementacji Bardziej skomplikowane dla prostych scenariuszy Prostsze dla prostych scenariuszy

ViewModel pomaga tworzyć bardziej odporne i łatwiejsze do testowania aplikacje, oddzielając UI od logiki przetwarzania danych.