【问题标题】:How do I get my Android Room database to re-populate?如何让我的 Android Room 数据库重新填充?
【发布时间】:2018-06-19 22:53:52
【问题描述】:

这是我的 AppDatabase 代码。我从 ChatUserChatMessage 开始,它们工作得很好,但后来我想添加 Wells。我把它们全部整理出来,并将它们与预初始化数据库的回调中的 2 行一起添加到这个类中。问题是这行不通。即使我更改版本号或卸载应用程序,数据库也不会预初始化。这是它工作时的第一个版本,所以我无法成功地迭代数据库。请帮忙!

@Database(entities = {ChatUser.class, ChatMessage.class, Well.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {

    private static AppDatabase INSTANCE;

    public abstract UserDao userDao();

    public abstract MessageDao messageDao();

    public abstract WellDao wellDao();

    public static AppDatabase getAppDatabase(final Context context) {
        Log.d("AppDatabase", "getting app database");
        if (INSTANCE == null) {
            INSTANCE =
                    Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "curadite-database")
                            .fallbackToDestructiveMigration()
                            .addCallback(new Callback() {
                                @Override
                                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                                    super.onCreate(db);
                                    Log.d("AppDatabase", "OnCreate");
                                    Executors.newSingleThreadExecutor().execute(new Runnable() {
                                        @Override
                                        public void run() {
                                            ChatUser user = new ChatUser("Me", true);
                                            ChatMessage message = new ChatMessage("Hello!", 1, System.currentTimeMillis());
                                            AppDatabase db = getAppDatabase(context);
                                            db.userDao().insertAll(user);
                                            db.messageDao().insertAll(message);
                                            Well[] wells = new Curapac(7, 2).flatWells();
                                            db.wellDao().insertAll(wells);
                                        }
                                    });
                                }
                            })
                            .build();
        }
        return INSTANCE;
    }

【问题讨论】:

    标签: java android android-sqlite android-room


    【解决方案1】:

    您的Callback 方法,使用线程让您的初始化发生在未来某个不可知的时间,不会非常可靠。不要求你的初始化工作在getAppDatabase()的调用者想要使用它的时候完成。

    要么:

    • onCreate() 内同步使用提供的SupportSQLiteDatabase 来填充您的数据库,或者

    • 在调用 build() 之后和退出 getAppDatabase() 方法中的 if 块之前填充数据库,检查当前数据库内容以查看是否需要执行初始化

    此外,您管理此单例的整体方法不能很好地处理同时调用getAppDatabase()。请将INSTANCE标记为volatile,并将getAppDatabase()标记为synchronized

    【讨论】:

    • 或者用@MainThread注释getAppDatabase(),如果是这样的话。
    • @TKK 不提供任何同步。此外,您不想在主应用程序线程上执行数据库 I/O。
    • 在这种情况下,它可能应该被注释为@WorkerThread。让它synchronized就足够了;不需要volatile
    猜你喜欢
    • 1970-01-01
    • 2019-11-25
    • 2021-11-29
    • 2017-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    相关资源
    最近更新 更多