Sobes.tech
Middle

Jak zapisać stan ViewModel w komponentach architektonicznych Androida?

sobes.tech AI

Odpowiedź od AI

Istnieje kilka sposobów na zapisanie stanu ViewModel:

  1. Użycie SavedStateHandle: Preferowaną metodą do zapisywania niewielkich ilości danych niezbędnych do przywrócenia stanu po zniszczeniu procesu. SavedStateHandle zapewnia interfejs podobny do mapy do przechowywania i pobierania danych.

    class MyViewModel(private val state: SavedStateHandle) : ViewModel() {
    
        private val _name = state.getLiveData<String>("name")
        val name: LiveData<String> = _name
    
        fun saveName(newName: String) {
            state.set("name", newName)
        }
    }
    
  2. Zapis stanu w bundle (Bundle): Używany razem z onSaveInstanceState do zapisywania danych samego Activity lub Fragment, a nie bezpośrednio ViewModel. Następnie te dane mogą być użyte do inicjalizacji ViewModel podczas jego tworzenia.

    // W Activity lub Fragment
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        // Zapis danych, które będą użyte do inicjalizacji ViewModel
        outState.putString("some_data_for_vm", "ważna wartość")
    }
    
    // Użycie danych w ViewModel (przez fabrykę)
    class MyViewModelFactory(private val initialData: String) : ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
                @Suppress("UNCHECKED_CAST")
                return MyViewModel(initialData) as T
            }
            throw IllegalArgumentException("Nieznana klasa ViewModel")
        }
    }
    
    class MyViewModel(private val initialData: String) : ViewModel() {
        // Użycie initialData do przywracania stanu
    }
    
  3. Zapis danych w pamięci trwałej: Dla bardziej złożonych lub większych danych można użyć SharedPreferences, baz danych (np. Room) lub plików. ViewModel może współpracować z repozytorium, które zarządza dostępem do tych danych.

    class MyViewModel(private val userRepository: UserRepository) : ViewModel() {
        fun saveUser(user: User) {
            userRepository.saveUser(user)
        }
    
        fun getUser(id: Long): LiveData<User> {
            return userRepository.getUser(id)
        }
    }
    
    // Przykład UserRepository
    class UserRepository(private val userDao: UserDao) {
        fun saveUser(user: User) {
            // Logika zapisywania do bazy danych
        }
    
        fun getUser(id: Long): LiveData<User> {
            // Logika pobierania z bazy danych
        }
    }
    

Wybór metody zależy od typu i ilości danych do zapisania oraz od scenariuszy przywracania stanu (np. zniszczenie procesu vs zmiana konfiguracji). SavedStateHandle jest najbardziej odpowiedni do przechowywania stanu, który musi przetrwać zniszczenie procesu i przywrócić UI.