Я создал базу данных Room с сущностями, DAO, базой данных и ViewModel. Кажется, у меня возникла проблема с ViewModel, вызывающим сбой моего приложения при запуске с двумя ошибками: java.lang.RuntimeException: Cannot create an instance of class com.whatamidoingwithmylife.splitbill.RestaurantViewModel
и java.lang.RuntimeException: Cannot create an instance of class com.whatamidoingwithmylife.splitbill.RestaurantViewModel
.
Вот полная трассировка стека:
07-05 20:35:57.244 23174-23174/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.whatamidoingwithmylife.splitbill, PID: 23174
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.whatamidoingwithmylife.splitbill/com.whatamidoingwithmylife.splitbill.SBSplash}: java.lang.RuntimeException: Cannot create an instance of class com.whatamidoingwithmylife.splitbill.RestaurantViewModel
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2684)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6186)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Caused by: java.lang.RuntimeException: Cannot create an instance of class com.whatamidoingwithmylife.splitbill.RestaurantViewModel
at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:205)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:133)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:101)
at com.whatamidoingwithmylife.splitbill.SBSplash.onCreate(SBSplash.java:28)
at android.app.Activity.performCreate(Activity.java:6684)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2637)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6186)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:197)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:133)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:101)
at com.whatamidoingwithmylife.splitbill.SBSplash.onCreate(SBSplash.java:28)
at android.app.Activity.performCreate(Activity.java:6684)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2637)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6186)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:164)
at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:192)
at com.whatamidoingwithmylife.splitbill.RestaurantDao_Impl.getAllRestaurants(RestaurantDao_Impl.java:77)
at com.whatamidoingwithmylife.splitbill.RestaurantRepository.<init>(RestaurantRepository.java:16)
at com.whatamidoingwithmylife.splitbill.RestaurantViewModel.<init>(RestaurantViewModel.java:15)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:197)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:133)
at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:101)
at com.whatamidoingwithmylife.splitbill.SBSplash.onCreate(SBSplash.java:28)
at android.app.Activity.performCreate(Activity.java:6684)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2637)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6186)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
Вот метод SBSplash.java
onCreate
:
private RestaurantViewModel mRestaurantViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sbsplash);
RecyclerView anotherOne = (RecyclerView) findViewById(R.id.recyclerview_id);
final RestaurantListAdapter adapter = new RestaurantListAdapter(this);
anotherOne.setLayoutManager(new GridLayoutManager(this,2));
anotherOne.setAdapter(adapter);
mRestaurantViewModel = ViewModelProviders.of(this).get(RestaurantViewModel.class);
}
Вот RestaurantRepository.java
:
private RestaurantDao mRestaurantDao;
private List<Restaurant> mAllRestaurants;
RestaurantRepository(Application application) {
SplitBillRoomDatabase db = SplitBillRoomDatabase.getDatabase(application);
mRestaurantDao = db.restaurantDao();
mAllRestaurants = mRestaurantDao.getAllRestaurants();
}
List<Restaurant> getAllRestaurants() {
return mAllRestaurants;
}
public void insert(Restaurant restaurant) {
new insertAsyncTask(mRestaurantDao).execute(restaurant);
}
private static class insertAsyncTask extends AsyncTask<Restaurant, Void, Void> {
private RestaurantDao mAsyncTaskDao;
insertAsyncTask(RestaurantDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Restaurant... params) {
return null;
}
}
Вот RestaurantViewModel.java
:
private RestaurantRepository mRepository;
private List<Restaurant> mAllRestaurants;
public RestaurantViewModel(Application application) {
super(application);
mRepository = new RestaurantRepository(application);
mAllRestaurants = mRepository.getAllRestaurants();
}
List<Restaurant> getAllRestaurants() {
return mAllRestaurants;
}
public void insert(Restaurant restaurant) {
mRepository.insert(restaurant);
}
Вот RestaurantDao.java
:
@Dao
public interface RestaurantDao {
@Query("SELECT * FROM Restaurants")
List<Restaurant> getAllRestaurants();
@Insert
void insert(Restaurant restaurant);
@Query("DELETE FROM Restaurants")
void deleteAll();
}
Редактировать: Вот Restaurant.java
:
package com.whatamidoingwithmylife.splitbill;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
@Entity(tableName = "Restaurants")
public class Restaurant {
@PrimaryKey(autoGenerate = true)
private int ResID;
@ColumnInfo(name = "ResName")
private String Name;
@ColumnInfo(name = "ResPicture")
private int PictureID;
public Restaurant(String Name, int PictureID) {
this.Name = Name;
this.PictureID = PictureID;
}
public int getPictureID() {
return PictureID;
}
public void setPictureID(int pictureID) {
PictureID = pictureID;
}
public String getName() {
return Name;
}
public int getResID() {
return ResID;
}
public void setResID(int resID) {
ResID = resID;
}
public void setName(String name) {
Name = name;
}
}