代码之家  ›  专栏  ›  技术社区  ›  Genaut

使用Room递归调用getDatabase

  •  0
  • Genaut  · 技术社区  · 8 年前

    我在活动类中执行getDatabase方法,但是我使用dao从数据库中获取信息,应用程序崩溃。这是我第一次接触Android房间,也许我忘记了一些重要的事情要做。有人能帮我吗?

    数据库类:

    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)
    

    @Query("SELECT * FROM entitysounds")
        List<EntitySounds> getAll();
    

    3 回复  |  直到 8 年前
        1
  •  6
  •   CommonsWare    8 年前

    但是我使用dao从数据库中获取信息

    这行不通,因为房间还没摆好。或者:

    • 在外面做这个工作 RoomDatabase.Callback

    • 请勿使用 ,而是使用 SupportSQLiteDatabase 作为参数提供给 onOpen() 以及其他回调方法

        2
  •  2
  •   DuDu    7 年前

    这是因为 onOpen() getDatabase 打电话。

    INSTANCE.soundsDao().deleteAllSounds() ,如果您查看 deleteAllSounds() 在里面 SoundsDao_Impl (Impl生成的文件 Dao s) ,你可以看到它在召唤 __db.beginTransaction() 哪一个会打电话 mOpenHelper.getWritableDatabase() .

    Exception 被抛出 getDatabase called recursively .

    修复是可以的 实例.soundsDao().deleteAllSounds() https://medium.com/androiddevelopers/7-pro-tips-for-room-fbadea4bfbd1

    ioThread {
        INSTANCE.soundsDao().deleteAllSounds()
    }
    
    ...
    
    private val IO_EXECUTOR = Executors.newSingleThreadExecutor()
    
    /**
     * Utility method to run blocks on a dedicated background thread, used for io/database work.
     */
    fun ioThread(f : () -> Unit) {
        IO_EXECUTOR.execute(f)
    }
    

    此处引用: https://gist.github.com/florina-muntenescu/697e543652b03d3d2a06703f5d6b44b5

        3
  •  1
  •   Moaz Rashad    6 年前

    Executors.newSingleThreadExecutor().execute {
        INSTANCE.soundsDao().deleteAllSounds(); 
    }
    
        4
  •  0
  •   Nurseyit Tursunkulov    7 年前

    我的朋友,我也有类似的问题。但对我来说,问题是我从两个不同的类获取数据库。当从第二个类中删除第二个初始化时,它起作用了。

    推荐文章