Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 成功调用.build()后,未调用RoomDatabase.Callback()的onCreate()_Android_Android Sqlite_Android Room_Sqliteopenhelper - Fatal编程技术网

Android 成功调用.build()后,未调用RoomDatabase.Callback()的onCreate()

Android 成功调用.build()后,未调用RoomDatabase.Callback()的onCreate(),android,android-sqlite,android-room,sqliteopenhelper,Android,Android Sqlite,Android Room,Sqliteopenhelper,我使用Room Perssdent lib创建了电影数据库。根据RoomDatabase.Callback中onCreate()方法的文档,onCreate() 在第一次创建数据库并创建所有表后调用 调用buildPersistentDB()后发生的事情是,我收到了MoviesDatabase类(用@Database注释的类)的日志,但RoomDatabase.Callback中onCreate()的日志是 尽管我打过电话,但从未打过电话: this.mMovieDatabase = this.

我使用Room Perssdent lib创建了电影数据库。根据RoomDatabase.Callback中onCreate()方法的文档,onCreate() 在第一次创建数据库并创建所有表后调用

调用buildPersistentDB()后发生的事情是,我收到了MoviesDatabase类(用@Database注释的类)的日志,但RoomDatabase.Callback中onCreate()的日志是 尽管我打过电话,但从未打过电话:

this.mMovieDatabase = this.mMovieDBPersistentBuilder.fallbackToDestructiveMigration().build();
buildPersistentDB()方法清楚地显示了我创建数据库的方式。 我还发布了MovieDatabase类,如下所示

我想知道为什么我没有从Room.Callback中的onCreate()方法接收日志,尽管数据库已成功创建

代码_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
//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
代码_2

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
//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
logcat

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
//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
2018-12-13 14:37:54.665 8949-8949 V/ActMain:->initPersistentDBHandlerThread RoomPersistentDBHandlerThread:RoomPersistentDBHandlerThread构造函数被调用。
2018-12-13 14:37:54.666 8949-8949 V/ActMain->RoomPersistentDBHandlerThread:initHandler被调用
2018-12-13 14:37:54.667 8949-8967 V/ActMain->RoomPersistentDBHandlerThread:onLooperPrepared被调用。[getLooper:Looper(ROOM_PERSISTENT_DB_HANDLER_THREAD,tid 356){cbdoffd}]++
2018-12-13 14:37:54.667 8949-8967 V/ActMain->RoomPersistentDBHandlerThread:+
2018-12-13 14:37:54.670 8949-8949 V/ActMain->RoomPersistentDBHandlerThread:enqueueMessage是为=1调用的
2018-12-13 14:37:54.670 8949-8967 V/ActMain->RoomPersistentDBHandlerThread:handleMessage是为msg调用的。what=1
2018-12-13 14:37:54.670 8949-8967 V/ActMain:->调用buildPersistentDB MovieDatabase构造函数。init被称为。buildPersistentDB:->this.mMovieDatabase.isOpen():false

没有调用OnCreate的原因是,在首次创建数据库时只调用一次,然后只要数据库存在,就不再调用它

如果删除应用程序的数据或卸载应用程序,然后重新运行,您将看到随后调用了onCreate

e、 g

删除应用程序的数据后,结果为:-

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

  • 卸载应用程序之前,请先删除手机设置中的应用程序数据

  • 手动删除数据库文件(设备文件资源管理器→ 资料→ 资料→
    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");
            }