Как получить экземпляр AndroidViewModel?
Я создал AndroidViewModel для основной активности.Теперь я хочу получить экземпляр AndroidViewModel в основной активности. Для этого я делаю следующее viewModal = new ViewModelProvider(this).get(MainViewModal.class);
Но при запуски, студия выкидывает следующую ошибку
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mymovies, PID: 4377
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.mymovies/com.example.mymovies.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.mymovies.data.MainViewModal
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.mymovies.data.MainViewModal
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.mymovies.MainActivity.onCreate(MainActivity.java:45)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.InstantiationException: java.lang.Class<com.example.mymovies.data.MainViewModal> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
at com.example.mymovies.MainActivity.onCreate(MainActivity.java:45)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Вот код Основной активности
package com.example.mymovies;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import com.example.mymovies.data.MainViewModal;
import com.example.mymovies.data.Movie;
import com.example.mymovies.utils.JSONUtils;
import com.example.mymovies.utils.NetworkUtils;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Switch switchSort;
private RecyclerView recyclerViewPosters;
private MovieAdapter movieAdapter;
private TextView textViewTopRated;
private TextView textViewPopularity;
private MainViewModal viewModal;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewModal = new ViewModelProvider(this).get(MainViewModal.class);
textViewTopRated = findViewById(R.id.textViewTopRated);
textViewPopularity = findViewById(R.id.textViewPopularity);
switchSort = findViewById(R.id.switchSort);
recyclerViewPosters = findViewById(R.id.recyclerViewPosters);
recyclerViewPosters.setLayoutManager(new GridLayoutManager(this, 2));
movieAdapter = new MovieAdapter();
recyclerViewPosters.setAdapter(movieAdapter);
switchSort.setChecked(true);
switchSort.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
setMethodOfSort(isChecked);
}
});
switchSort.setChecked(false);
movieAdapter.setOnPosterClickListener(new MovieAdapter.OnPosterClickListener() {
@Override
public void onPosterClick(int position) {
Toast.makeText(MainActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
movieAdapter.setOnReachEndListener(new MovieAdapter.OnReachEndListener() {
@Override
public void onReachEnd() {
Toast.makeText(MainActivity.this, "Конец списка", Toast.LENGTH_SHORT).show();
}
});
LiveData<List<Movie>> moviesFromLiveData = viewModal.getMovies();
moviesFromLiveData.observe(this, new Observer<List<Movie>>() {
@Override
public void onChanged(List<Movie> movies) {
movieAdapter.setMovies(movies);
}
});
}
public void onClickSetPopularity(View view) {
setMethodOfSort(false);
switchSort.setChecked(false);
}
public void onClickTopRated(View view) {
setMethodOfSort(true);
switchSort.setChecked(true);
}
private void setMethodOfSort(boolean isTopRated) {
int methodOfSort;
if (isTopRated) {
textViewTopRated.setTextColor(getResources().getColor(R.color.colorAccent));
textViewPopularity.setTextColor(getResources().getColor(R.color.white));
methodOfSort = NetworkUtils.TOP_RATED;
} else {
textViewTopRated.setTextColor(getResources().getColor(R.color.white));
textViewPopularity.setTextColor(getResources().getColor(R.color.colorAccent));
methodOfSort = NetworkUtils.POPULARITY;
}
downloadData(methodOfSort, 1);
}
private void downloadData(int methodOfSort, int page) {
JSONObject jsonObject = NetworkUtils.getJSONFromNetwork(methodOfSort, page);
ArrayList<Movie> movies = JSONUtils.getMoviesFromJSON(jsonObject);
if (movies != null && !movies.isEmpty()) {
viewModal.deleteAllMovies();
for (Movie i :
movies) {
viewModal.insertMovie(i);
}
}
}
}
А вот код ViewModel
package com.example.mymovies.data;
import android.app.Application;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class MainViewModal extends AndroidViewModel {
private static MovieDataBase dataBase;
private LiveData<List<Movie>> movies;
public MainViewModal(@NonNull Application application) {
super(application);
dataBase = MovieDataBase.getInstance(getApplication());
movies = dataBase.movieDao().getAllMovies();
}
public Movie getMovieById(int id) {
try {
return new GetMovieTask().execute(id).get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public void deleteAllMovies() {
new DeleteMovieTask().execute();
}
public void deleteMovies(Movie movie) {
new DeleteTask().execute(movie);
}
public void insertMovie(Movie movie) {
new InsertTask().execute(movie);
}
public MainViewModal(@NonNull Application application, LiveData<List<Movie>> movies) {
super(application);
this.movies = movies;
}
private static class DeleteTask extends AsyncTask<Movie, Void, Void> {
@Override
protected Void doInBackground(Movie... movies) {
if (movies != null && movies.length > 0) {
dataBase.movieDao().deleteMovie(movies[0]);
}
return null;
}
}
private static class InsertTask extends AsyncTask<Movie, Void, Void> {
@Override
protected Void doInBackground(Movie... movies) {
if (movies != null && movies.length > 0) {
dataBase.movieDao().insertMovie(movies[0]);
}
return null;
}
}
private static class DeleteMovieTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
dataBase.movieDao().deleteAllMovies();
return null;
}
}
private static class GetMovieTask extends AsyncTask<Integer, Void, Movie> {
@Override
protected Movie doInBackground(Integer... integers) {
if (integers != null && integers.length > 0) {
return dataBase.movieDao().getMovieById(integers[0]);
}
return null;
}
}
public LiveData<List<Movie>> getMovies() {
return movies;
}
}
Ответы (1 шт):
Автор решения: Ziotyr
→ Ссылка
Оказывается в Активности нужно было вместо
viewModal = new ViewModelProvider(this).get(MainViewModal.class);
написать
viewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(PostViewModel.class);