我在尝试初始化数据库时遇到错误。我正在使用Android Room,我想使用RoomDatabaseBuilder来执行回调并填充我的数据库。
我在Activity类中执行getDatabase方法,但后来我使用dao从数据库获取信息,应用程序崩溃。这是我与Android Room的第一次联系,也许我正在伪造一些重要的事情。有人可以帮我这个吗?
数据库类:
static RoomDatabase.Callback rdc = new RoomDatabase.Callback() {
@Override
public void onOpen(@NonNull SupportSQLiteDatabase db) {
super.onOpen(db);
Log.d(TAG, "Debug: onOpen");
//Borramos todos los sonidos de la base de datos
INSTANCE.soundsDao().deleteAllSounds(); // Instance is "private static DatabaseSounds INSTANCE;"
崩溃的活动线来源:
db = DatabaseSounds.getDatabase(getApplicationContext());
AsyncTask task = new LoadGridAsyncTask().execute(); **
private class LoadGridAsyncTask extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... voids) {
//Extraemos el listado de sonidos y los convertimos a DTO
List<EntitySounds> listSounds = db.soundsDao().getAll(); **** THIS is the line of crash
这是错误
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.IllegalStateException: getDatabase called recursively
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:203)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:96)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
at android.arch.persistence.room.RoomDatabase.compileStatement(RoomDatabase.java:244)
at android.arch.persistence.room.SharedSQLiteStatement.createNewStatement(SharedSQLiteStatement.java:65)
at android.arch.persistence.room.SharedSQLiteStatement.getStmt(SharedSQLiteStatement.java:72)
at android.arch.persistence.room.SharedSQLiteStatement.acquire(SharedSQLiteStatement.java:87)
at com.genaut.myapp.database.dao.DaoSounds_Impl.deleteAllSounds(DaoSounds_Impl.java:140)
at com.genaut.myapp.database.DatabaseSounds$1.onOpen(DatabaseSounds.java:57)
at com.genaut.myapp.database.DatabaseSounds_Impl$1.onOpen(DatabaseSounds_Impl.java:65)
at android.arch.persistence.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:111)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:149)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:266)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:96)
at android.arch.persistence.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:54)
at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:233)
at com.genaut.myapp.database.dao.DaoSounds_Impl.getAll(DaoSounds_Impl.java:155)
at com.genaut.myapp.Home$LoadGridAsyncTask.doInBackground(Home.java:83)
at com.genaut.myapp.Home$LoadGridAsyncTask.doInBackground(Home.java:78)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
这是Dao方法:
@Query("SELECT * FROM entitysounds")
List<EntitySounds> getAll();
答案 0 :(得分:4)
然后我使用dao从数据库中获取信息
这不起作用,因为Room尚未设置。之一:
在b
或
请勿在{{1}}内使用Room,而是使用RoomDatabase.Callback
作为RoomDatabase.Callback
参数提供的SupportSQLiteDatabase
以及其他回调方法
答案 1 :(得分:1)
在新的单独线程中运行
Executors.newSingleThreadExecutor().execute {
INSTANCE.soundsDao().deleteAllSounds();
}
答案 2 :(得分:0)
我的朋友,我遇到类似的问题。但是对我来说,问题是我从两个不同的类中获取数据库。从第二个类中删除第二个初始化后,它就起作用了。
答案 3 :(得分:0)
之所以会这样,是因为已经有onOpen()
被调用时调用了回调的getDatabase
。
然后在第INSTANCE.soundsDao().deleteAllSounds()
行,如果您在deleteAllSounds()
(SoundsDao_Impl
s的Impl生成文件)中查看Dao
的实现,则可以看到它调用{{ 1}},它将调用__db.beginTransaction()
。
这是抛出mOpenHelper.getWritableDatabase()
的地方Exception
。
可以将该修复程序getDatabase called recursively
放在此参考文献中的另一个线程中:https://medium.com/androiddevelopers/7-pro-tips-for-room-fbadea4bfbd1
INSTANCE.soundsDao().deleteAllSounds()
此处参考:https://gist.github.com/florina-muntenescu/697e543652b03d3d2a06703f5d6b44b5