web-dev-qa-db-fra.com

Impossible de créer une instance de la classe ViewModel (Impossible de démarrer l'activité ComponentInfo)

J'utilise MVVM, Retrofit, LiveData dans mon projet mais j'obtiens cette erreur avant que je voie ces liens

Erreur

Java.lang.RuntimeException:       
Unable to start activity ComponentInfo{ir.orangehat.movieinfo/ir.orangehat.movieinfo.application.home.HomeActivity}: Java.lang.RuntimeException:

Cannot create an instance of class ir.orangehat.movieinfo.application.home.HomeViewModel

Ceci est mon ViewModel et je pense que le problème est dans mon constructeur

public class HomeViewModel extends AndroidViewModel {

private MovieRepository movieRepository;

public HomeViewModel(@NonNull Application application, Context context, LifecycleOwner lifecycleOwner) {
    super(application);
    movieRepository = new MovieRepository(lifecycleOwner, context);
}

LiveData<List<Movie>> getMovies() {
    return movieRepository.getMovies();
}}

Dépôt

public class MovieRepository extends BaseRepository {

private LifecycleOwner lifecycleOwner;
private MovieApi movieApi;
private MovieDatabaseHelper movieDatabaseHelper;

public MovieRepository(LifecycleOwner lifecycleOwner, Context context) {
    this.lifecycleOwner = lifecycleOwner;
    movieApi = getRetrofitHelper().getService(MovieApi.class);
    movieDatabaseHelper = new MovieDatabaseHelper(context);
}

public LiveData<List<Movie>> getMovies() {
    LiveData<List<Movie>> moviesLiveData = movieApi.getMovieList();
    moviesLiveData.observe(lifecycleOwner, new Observer<List<Movie>>() {
        @Override
        public void onChanged(@Nullable List<Movie> movieArrayList) {
            movieDatabaseHelper.Save(movieArrayList);
        }
    });

    return movieDatabaseHelper.getAll();
} }

Classe d'activité

public class HomeActivity extends AppCompatActivity {

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

    // the error is here
    HomeViewModel homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);

    homeViewModel.getMovies().observe(HomeActivity.this, new Observer<List<Movie>>() {
        @Override
        public void onChanged(@Nullable List<Movie> movieArrayList) {
            String str = null;
            if (movieArrayList != null) {
                str = Arrays.toString(movieArrayList.toArray());
            }
            Log.e("movies", str);
        }
    });
}

}

Devrais-je utiliser Dagger dans mon projet et mon usine personnalisée?

3
Sina Rahimi

Citation la documentation pour AndroidViewModel :

Les sous-classes doivent avoir un constructeur qui accepte Application comme seul paramètre. 

Votre constructeur ne répond pas à cette exigence.

Non plus:

  • Supprimez les paramètres de constructeur Context context et LifecycleOwner lifecycleOwner de votre HomeViewModel, ou

  • Créez un ViewModelProvider.Factory qui peut construire vos instances HomeViewModel et utilisez cette fabrique avec ViewModelProviders.of()

8
CommonsWare

Si ça aide quelqu'un. Dans mon cas, tout ce que CommonsWare avait dit était juste, cependant, j'ai oublié d'injecter l'AppComponennt.

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        // this line was missing
        ((BaseApplication) getApplication()).getAppComponent().inject(this); 
        super.onCreate(savedInstanceState);
}
0
Soon Santos

Essayez d'ajouter ceci:

private LiveData<Section[]> movies;

Et puis, changez ceci:

LiveData<List<Movie>> getMovies() {
    if(movies==null)
        movies= movieRepository.getMovies();
    return movies;
}

Cela a fonctionné pour moi.

0
Jhon Paul
    In HomeViewModel class need to extend ViewModel class.


public class MovieListViewModel extends ViewModel {
        private MutableLiveData<MovieModel> data;
        private MovieRepository movieModel;

        public MovieListViewModel() {
            movieModel = new MovieRepository();
        }

        public void init() {
            if (this.data != null) {
                // ViewModel is created per Fragment so
                // we know the userId won't change
                return;
            }
            data = movieModel.getMovies();
        }

        public MutableLiveData<MovieModel> getMovies() {
            return this.data;
        }
    }

https://github.com/kamydeep00178/androidMvvm peut également consulter un exemple complet

0
Kamal Kakkar