使用Room,Dao将数据输入数据库时​​出错

时间:2019-08-01 11:55:34

标签: android android-room android-livedata

这是我第一次使用Room和LiveData。我不断收到有关使用Dao(数据库访问对象)将数据输入数据库的错误。我尝试更新build.gradle文件,但不能解决错误。它说“ getDatabase递归调用”。

我的日志如下:

 2019-08-01 13:35:55.644 18117-18149/com.example.inventory E/AndroidRuntime: FATAL EXCEPTION: arch_disk_io_0
    Process: com.example.inventory, PID: 18117
    java.lang.RuntimeException: Exception while computing database live data.
        at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.lang.IllegalStateException: getDatabase called recursively
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:338)
        at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:298)
        at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:92)
        at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:53)
        at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:452)
        at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:275)
        at com.example.inventory.data.InventoryDao_Impl.insert(InventoryDao_Impl.java:58)
        at com.example.inventory.data.InventoryRoomDatabase$PopulateDbAsync.<init>(InventoryRoomDatabase.java:46)
        at com.example.inventory.data.InventoryRoomDatabase$1.onOpen(InventoryRoomDatabase.java:34)
        at com.example.inventory.data.InventoryRoomDatabase_Impl$1.onOpen(InventoryRoomDatabase_Impl.java:58)
        at androidx.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:120)

房间数据库类

@Database(entities = Product.class, version = 1, exportSchema = false)
public abstract class InventoryRoomDatabase extends RoomDatabase {

    public abstract InventoryDao inventoryDao();

    public static InventoryRoomDatabase INSTANCE;

    public static InventoryRoomDatabase getDatabase(final Context context) {
        synchronized (InventoryRoomDatabase.class) {
            if (INSTANCE == null) {
                INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                        InventoryRoomDatabase.class, "inventory_table")
                        .fallbackToDestructiveMigration().addCallback(roomDatabaseCallback).build();
            }
        }
        return INSTANCE;
    }

    private static RoomDatabase.Callback roomDatabaseCallback = new RoomDatabase.Callback() {
        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);
            new PopulateDbAsync(INSTANCE).execute();

        }
    };

    private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> {

        private final InventoryDao mDao;
        Product product = new Product("Ice cream", 0.99, 70);

        PopulateDbAsync(InventoryRoomDatabase db) {
            mDao = db.inventoryDao();
            mDao.insert(product);
        }

        @Override
        protected Void doInBackground(Void... voids) {
            return null;
        }
    }
}

Dao界面

@Dao
public interface InventoryDao {

    @Insert
    void insert(Product product);

    @Query("DELETE FROM inventory_table")
    void deleteAll();

    @Query("SELECT * from inventory_table")
    LiveData<List<Product>> getAllProducts();
}

1 个答案:

答案 0 :(得分:2)

您的db数据插入过程正在主线程上进行,并且没有权限访问主线程上的room db,访问​​主线程上的db尝试以下代码。

 Room.databaseBuilder(AppInjector.getApplication(), AppDb.class, DbConstant.DATABASENAME)
                .fallbackToDestructiveMigration()
                .allowMainThreadQueries()
                .build()