android - 使用 Room、Dao 将数据输入数据库时​​出错

标签 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;
        }
    }
}

道接口(interface)

@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();
}

最佳答案

您的数据库数据插入进程正在主线程上运行,并且没有权限访问主线程上的房间数据库,要访问主线程上的数据库,请尝试以下代码。

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

关于android - 使用 Room、Dao 将数据输入数据库时​​出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57308483/

相关文章:

android - 尝试在空对象引用上调用虚拟方法 'void android.arch.lifecycle.MutableLiveData.setValue(java.lang.Object)'

androidTest 中的 Android LiveData 返回 null

android - Javascript 接口(interface),错误 "Uncaught Error: Error calling method on NPObject"

java - Android 中的 SSH 和隧道

android - map 的房间类型转换器

java - Android Retrofit2/RxJava2/Room——简单的数据处理

android - 房间用户可按查询配置顺序

安卓架构组件 : How is LiveData in the repository observed by a ViewModel

android - 原因 : buildOutput. apkData 不能为空

android - 唤醒锁在 Nexus 5 上不断抛出异常