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"
si vous utilisez Hilt, vous avez probablement oublié d'annoter votre activité avec @androidentitryRyPoint
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
.
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.