Как я могу создать ViewModel, которая обращается к данным из базы данных Room, не вызывая RuntimeException? - PullRequest
0 голосов
/ 05 июля 2018

Я создал базу данных 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;
}

}

1 Ответ

0 голосов
/ 06 июля 2018

НВМ исправил это

Окей, шутки в сторону, я исправил это, внедрив LiveData вокруг всех java.util.List, которые я использовал. Каким-то образом это исправило это, я не собираюсь задавать дальнейшие вопросы о том, почему это работает, это просто работает, и я рад, что это сработало. Спасибо за вашу помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...