OnCreate () из RoomDatabase.Callback () не был вызван после успешного вызова .build ()

Я создал MovieDatabase, используя Room Persisdent lib. Согласно документации метода onCreate () в RoomDatabase.Callback, onCreate () для вызова после первого создания базы данных и создания всех таблиц.

Что случилось после того, как я вызвал buildPersistentDB (), я получил журналы из класса MoviesDatabase, класса, аннотированного с помощью @Database, но журналы из onCreate () в RoomDatabase.Callback были ни разу не позвонил, хотя я звонил:

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

Способ создания базы данных четко показан в методе buildPersistentDB (). Я также разместил класс MovieDatabase, как показано ниже.

Я хотел бы знать, почему я не получил журналы из метода onCreate () в Room.Callback, несмотря на то, что база данных была успешно создана

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.");
}
}

логарифм:

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
3
0
3 879
2

Ответы 2

Причина, по которой OnCreate не вызывается, заключается в том, что он вызывается только один раз при первом создании базы данных и никогда больше, пока база данных существует.

Если вы удалите данные приложения или удалите приложение, а затем повторно запустите его, вы увидите, что затем вызывается onCreate.

например

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

После удаления данных приложения: -

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.

Метод Oncreate вызывается после создания базы данных. База данных комнат - это абстракция SQLiteOpenHelper. База данных создается при вызове getReadableDatabase () или getWriteableDatabase (). Поэтому до тех пор, пока не будет выполнена какая-то конкретная операция, например вызов метода @Dao, который попадает в базу данных, база данных не будет создана.

Чтобы решить проблему, воспользуйтесь одним из следующих вариантов.

  • Выполните некоторые операции, включая @delete, @insert или @update

    или

  • Перед удалением приложения удалите данные приложения в настройках телефона.

    или

  • Удалите файлы db вручную (проводник устройства → данные → данные → com.company.yourapp → базы данных в Android Studio).

    или

  • Вызовите в своем проекте следующий код:

    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");
            }
    

Другие вопросы по теме