web-dev-qa-db-fra.com

AndroidViewModel n'a pas de constructeur zéro argument

J'essaie de créer une instance de mon AndroidViewModel en maadactivité. Quand je fais cela, je reçois l'erreur suivante n'a pas de constructeur d'arguments zéro

Voici mon récipèveviewModel

package com.example.kookrecepten;

import Android.app.Application;

import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;

import Java.util.List;

public class RecipeViewModel extends AndroidViewModel {
    private RecipeRepository recipeRepository;
    private LiveData<List<Recipe>> allRecipes;

    public RecipeViewModel(Application application) {
        super(application);
        recipeRepository = new RecipeRepository(application);
        allRecipes = recipeRepository.getAllRecipes();
    }

    public void insert(Recipe recipe) {
        recipeRepository.insert(recipe);
    }

    public void update(Recipe recipe) {
        recipeRepository.update(recipe);
    }

    public void delete(Recipe recipe) {
        recipeRepository.delete(recipe);
    }

    public void deleteAll() {
        recipeRepository.deleteAllRecipes();
    }

    public LiveData<List<Recipe>> getAllRecipes() {
        return allRecipes;
    }
}

Maintenant, corrigez-moi si je me trompe mais AndroidViewModel a besoin du contexte de l'application dans le constructeur et la viewModel. Je n'ai donc aucune idée de pourquoi Android Demande un constructeur d'arguments zéro.

Voici mon activité principale où je demande une instance.

package com.example.kookrecepten;

import Android.os.Bundle;
import Android.view.View;
import Android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.example.kookrecepten.databinding.ActivityMainBinding;

import Java.util.List;


public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding binding;
    private RecipeViewModel recipeViewModel;

    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);

        //Get an instance of the RecipeViewModel.
        recipeViewModel = new ViewModelProvider(this).get(RecipeViewModel.class);
        recipeViewModel.getAllRecipes().observe(this, new Observer<List<Recipe>>() {
            @Override
            public void onChanged(List<Recipe> recipes) {
                //Update recycle view

                Toast.makeText(MainActivity.this, "triggered", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Et ceci sont mes implémentations.

def lifecycle_version = "2.2.0"
def room_version = "2.2.5"

//LifeCycle Components
    // ViewModel
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
    // LiveData
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    // Annotation processor
    implementation "androidx.lifecycle:lifecycle-common-Java8:$lifecycle_version"

    //Room Components
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
10
Ruben

si vous utilisez Hilt, vous avez probablement oublié d'annoter votre activité avec @androidentitryRyPoint

0
HUSSENI ABDULHAKEEM

J'avais un coup d'œil à Android code source. Si votre activité étendait la classe Activity, au lieu de AppCompatActivity vous n'auriez pas vu ce problème. Le Classe Activity fournit une implémentation de l'interface HasDefaultViewModelProviderFactory qui fournit une usine correcte pour les classes d'extension AndroidViewModel. Malheureusement, AppCompatActivity ne met toujours pas en œuvre cette interface, et ensuite, pas de correction. L'usine est disponible. Donc, vous fournissez l'usine comme vous l'avez fait ou que vous pourriez implémenter vous-même, l'interface HasDefaultViewModelProviderFactory.

1
Omar BELKHODJA

Pouvez-vous essayer avec l'ancien, obsolète

recipeViewModel = ViewModelProviders.of(this).get(RecipeViewModel.class);

Cela a définitivement utilisé pour travailler dans nos applications. Si vous êtes le type aventureux, vous pouvez également utiliser le débogueur et entrer dans la méthode Get () de la vue de la vue pour vérifier comment il tente d'obtenir une instance de la viewModel.

0
Ridcully