es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cuándo se llama al constructor de un Viewmodel en Android?

Estoy pasando por este codelab: https://developer.android.com/codelabs/android-lifecycles#6
Explica cómo usar SavedStateHandle en un ViewModel para sobrevivir a la muerte del proceso. El constructor de la ViewModel es el siguiente:

private SavedStateHandle mState;

public SavedStateViewModel(SavedStateHandle savedStateHandle) {
   mState = savedStateHandle;
}

Y el ViewModel se inicializa en la actividad de la siguiente manera:

mSavedStateViewModel = new ViewModelProvider(this).get(SavedStateViewModel.class);

¿Cuándo se llama al constructor del ViewModel? ¿Y cómo obtiene la ViewModel el parámetro savedStateHandle del ViewModel?

Edición:

Encontré la respuesta a mi pregunta a través de esta publicación de blog:
https://www.rockandnull.com/viewmodel-savedstate/

Dice que si SavedStateHandle es el único parámetro en el constructor de nuestro ViewModel, la delegación by viewModels lo proporciona automáticamente al ViewModel.

Sin embargo,
Si tenemos una combinación de parámetros personalizados proporcionados por el marco de inyección de dependencias (Hilt), por ejemplo, el repositorio, un par de otros argumentos en tiempo de ejecución, como el ID de categoría seleccionada y el SavedStateHandle para ayudarnos a sobrevivir a la muerte del proceso en el constructor del ViewModel, ¿cómo podemos proporcionar todos esos parámetros a la fábrica?

Por favor, publique un pequeño ejemplo para mi comprensión.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Si tenemos parámetros personalizados además de SavedStateHandle en el constructor de ViewModel, podemos crear una clase de fábrica de ViewModel personalizada para proporcionar esos parámetros al crear el ViewModel. Aquí hay un ejemplo:

    Primero, cree una clase de fábrica de ViewModel que extienda AbstractSavedStateViewModelFactory:

    class MyViewModelFactory(
        private val repository: MyRepository,
        private val categoryId: String,
        owner: SavedStateRegistryOwner,
        defaultArgs: Bundle = Bundle()
    ) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
    
        override fun <t :="" viewmodel?=""> create(
            key: String,
            modelClass: Class<t>,
            handle: SavedStateHandle
        ): T {
            if (modelClass.isAssignableFrom(MyViewModel::class.java)) {
                @Suppress("UNCHECKED_CAST")
                return MyViewModel(repository, categoryId, handle) as T
            }
            throw IllegalArgumentException("Unknown ViewModel class")
        }
    }
    

    En el método create, proporcionamos el repository, categoryId y handle al constructor de ViewModel. También verificamos que la clase ViewModel solicitada sea MyViewModel.

    Luego, usamos MyViewModelFactory para crear nuestro ViewModel:

    class MyActivity : AppCompatActivity() {
    
        private val viewModel: MyViewModel by viewModels {
            MyViewModelFactory(myRepository, "123", this)
        }
    
        // ...
    }
    

    Aquí, creamos una instancia de MyViewModelFactory, pasando nuestras dependencias (repository y categoryId), así como el SavedStateRegistryOwner (que suele ser la actividad o fragmento). Luego usamos el delegado by viewModels para crear nuestra instancia de MyViewModel, pasando MyViewModelFactory como parámetro al delegado.

    Ahora, cuando se cree MyViewModel, recibirá los parámetros repository, categoryId y handle en su constructor.

Comments are closed.