onCreate() of RoomDatabase.Callback() was not called after a successful call to .build()

对着背影说爱祢 提交于 2020-12-11 08:59:47

问题


I have created MovieDatabase using Room Persisdent lib. According to the documentation of onCreate() method in RoomDatabase.Callback, onCreate() to be called after the database is created for the first time, and all the tables were created.

What happend after I called buildPersistentDB() is, I received logs from MoviesDatabase class, the class that is annotated with @Database, but the logs from onCreate() in RoomDatabase.Callback were never called despite I called:

this.mMovieDatabase = this.mMovieDBPersistentBuilder.fallbackToDestructiveMigration().build();

The way I created the database is clearly shown in the buildPersistentDB() method. I also posted MovieDatabase class as shown below.

I would like to know why I did not receive logs from onCreate() method in Room.Callback despite the database was created successfully

code_1:

public void buildPersistentDB() {
    Log.v(TAG_LOG, "->buildPersistentDB");
    this.mMovieDBPersistentBuilder = Room
            .databaseBuilder(getApplicationContext(), MovieDatabase.class, ActMain.DATA_BASE_NAME);

    this.mMovieDBPersistentBuilder.addCallback(new RoomDatabase.Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            Log.v(TAG_LOG + "->onCreate", " buildPersistentDB->DB is created, all tables has been created");
            Log.d(TAG_LOG + "->onCreate", " buildPersistentDB->DB db.getPath(): " + db.getPath());
            Log.d(TAG_LOG + "->onCreate", " buildPersistentDB->DB db.toString(): " + db.toString());
            Log.d(TAG_LOG + "->onCreate", " buildPersistentDB->DB db.isOpen(): " + db.isOpen());
            Log.d(TAG_LOG + "->onCreate", " buildPersistentDB->DB db.isReadOnly(): " + db.isReadOnly());
        }

        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);
            Log.v(TAG_LOG + "->onOpen", " buildPersistentDB->onCreate");
            Log.d(TAG_LOG + "->onOpen", " buildPersistentDB->DB has been opened");
        }
    });
    this.mMovieDatabase = this.mMovieDBPersistentBuilder.fallbackToDestructiveMigration().build();
     Log.d(TAG_LOG + "->buildPersistentDB", "->this.mMovieDatabase.isOpen(): " + this.mMovieDatabase.isOpen());
}//eof-buildPersistentDB

code_2:

//class - The abstract class which is annotated with Database and extends RoomDatabase.
@Database(entities = {Movie.class}, version = 1, exportSchema = false)
public abstract class MovieDatabase extends RoomDatabase {
private final static String TAG_LOG = MovieDatabase.class.getSimpleName();

public abstract IDatabaseAccessObject dao();

public MovieDatabase() {
    super();
    Log.w(TAG_LOG, "->MovieDatabase constructor is called.");
}

@Override
public void init(@NonNull DatabaseConfiguration configuration) {
    super.init(configuration);
    Log.w(TAG_LOG, "->init is called.");
}

@NonNull
@Override
public SupportSQLiteOpenHelper getOpenHelper() {
    Log.w(TAG_LOG, "->init is called.");
    return super.getOpenHelper();
}

@NonNull
@Override
protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) {
    Log.w(TAG_LOG, "->createOpenHelper is called.");
    Log.d(TAG_LOG, "->createOpenHelper->config.name:" + config.name);
    Log.d(TAG_LOG, "->createOpenHelper->config.callbacks:" + config.callbacks);
    Log.d(TAG_LOG, "->createOpenHelper->config.requireMigration:" + config.requireMigration);
    return null;
}

@NonNull
@Override
protected InvalidationTracker createInvalidationTracker() {
    Log.w(TAG_LOG, "->createInvalidationTracker is called.");
    return null;
}

@Override
public void clearAllTables() {
    Log.w(TAG_LOG, "->clearAllTables is called.");
}
}

logcat:

2018-12-13 14:37:54.665 8949-8949 V/ActMain: ->initPersistentDBHandlerThread <-
2018-12-13 14:37:54.666 8949-8949 V/ActMain->RoomPersistentDBHandlerThread: RoomPersistentDBHandlerThread constructor is called.
2018-12-13 14:37:54.666 8949-8949 V/ActMain->RoomPersistentDBHandlerThread: initHandler is called
2018-12-13 14:37:54.667 8949-8967 V/ActMain->RoomPersistentDBHandlerThread: onLooperPrepared is called. [getLooper: Looper (ROOM_PERSISTENT_DB_HANDLER_THREAD, tid 356) {cbd0ffd}] ++++++++++++++++++++++++ 
2018-12-13 14:37:54.667 8949-8967 V/ActMain->RoomPersistentDBHandlerThread: ++++++++++++++++++++++++  [getLooper: Looper (ROOM_PERSISTENT_DB_HANDLER_THREAD, tid 356) {cbd0ffd}] ++++++++++++++++++++++++ 
2018-12-13 14:37:54.670 8949-8949 V/ActMain->RoomPersistentDBHandlerThread: enqueueMessage is called for what = 1
2018-12-13 14:37:54.670 8949-8967 V/ActMain->RoomPersistentDBHandlerThread: handleMessage is called for msg.what = 1
2018-12-13 14:37:54.670 8949-8967 V/ActMain: ->buildPersistentDB <-
2018-12-13 14:37:54.673 8949-8967 W/MovieDatabase: ->MovieDatabase constructor is called. <-
2018-12-13 14:37:54.673 8949-8967 W/MovieDatabase: ->init is called. <-
2018-12-13 15:02:54.802 9384-9403 D/ActMain->buildPersistentDB: ->this.mMovieDatabase.isOpen(): false

回答1:


The reason why OnCreate isn't being called is because it is only called once when the database is first created and then never again as long as the database exists.

If you delete the App's data or uninstall the App and then rerun it you will see that onCreate is then called.

e.g.

private void BuildDatabase() {
   RoomDatabase.Builder roombuilder = Room.databaseBuilder(this, Database.class,"mydb");
   roombuilder.addCallback(new RoomDatabase.Callback() {
       @Override
       public void onCreate(@NonNull SupportSQLiteDatabase db) {
           super.onCreate(db);
           Log.d("ONCREATE","Database has been created.");
       }

       @Override
       public void onOpen(@NonNull SupportSQLiteDatabase db) {
           super.onOpen(db);
           Log.d("ONOPEN","Database has been opened.");
       }
   });
   mRoomDB = (Database) roombuilder.build();
}

After deleting the App's data results in :-

2018-12-20 06:36:23.045 2271-2287/so53839431.so53839431roomrelationship D/ONCREATE: Database has been created.
2018-12-20 06:36:23.055 2271-2287/so53839431.so53839431roomrelationship D/ONOPEN: Database has been opened.



回答2:


Oncreate method is called once the database is created. Room database is abstraction of SQLiteOpenHelper. Database created when getReadableDatabase() or getWriteableDatabase() called. So until some concrete operation is performed, such as invoking a @Dao method that hits the database, database will not be created.

To solve the issue you should apply one of below options.

  • Perform some operations including @delete, @insert or @update

    or

  • Delete app data in phone's settings before you uninstall an app

    or

  • Delete your db files manually (device file explorer → data → data → com.company.yourapp → databases on Android Studio).

    or

  • Call the following code in your project:

    public void deleteDatabaseFile(String databaseName) { 
                File databases = 
                       new File(getApplicationInfo().dataDir + "/databases");
                File db = new File(databases, databaseName);
    
                if (db.delete())
                    Timber.d("Database deleted successfully");
                else
                    Timber.d("Failed to delete database");
            }
    


来源:https://stackoverflow.com/questions/53763787/oncreate-of-roomdatabase-callback-was-not-called-after-a-successful-call-to

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!