You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android重启后Room数据库重复预填充,修改数据无法持久化的解决咨询

Room数据库仅首次启动预填充,避免修改数据丢失

你的问题根源在于当前代码的预填充逻辑:createFromAsset会在数据库文件不存在时从资产目录复制,但搭配fallbackToDestructiveMigration后,一旦出现版本兼容问题(哪怕版本号没变,调试时的一些操作也可能触发),数据库会被销毁重建,导致之前的修改全部丢失。要实现仅首次安装时预填充,需要先判断数据库是否已存在,再决定是否执行预填充。

解决方案代码

修改AppDataBase的getInstance方法,添加数据库存在性检查:

@Database(entities = {DeviceInfo.class, AddressInfo.class}, version = 1)
public abstract class AppDataBase extends RoomDatabase {
    public abstract DeviceDao deviceDao();
    public abstract AddressDao addressDao();
    private static AppDataBase instance;

    public static synchronized AppDataBase getInstance(Context context) {
        if (instance == null) {
            // 获取App私有目录下的数据库文件路径
            File dbFile = context.getApplicationContext().getDatabasePath("device.db");
            boolean isDbExists = dbFile.exists();

            RoomDatabase.Builder<AppDataBase> dbBuilder = Room.databaseBuilder(
                    context.getApplicationContext(),
                    AppDataBase.class,
                    "device.db"
            );

            // 仅当数据库未创建时,才从资产文件预填充
            if (!isDbExists) {
                dbBuilder.createFromAsset("device.db");
            }

            // 注意:建议移除fallbackToDestructiveMigration,它会在迁移失败时销毁旧库
            // 若需要版本迁移,请编写对应的Migration类,避免数据丢失
            // .fallbackToDestructiveMigration()

            instance = dbBuilder.build();
        }
        return instance;
    }
}

关键说明

  • 数据库存在性判断:通过getDatabasePath拿到数据库的实际存储路径,检查文件是否存在,确保只有首次启动时才执行预填充
  • 移除破坏性迁移:fallbackToDestructiveMigration是一把双刃剑,它会在版本不兼容时直接删除旧数据库重建,这是调试阶段数据丢失的常见诱因。如果需要版本迭代,请编写Migration类来处理数据迁移,而非依赖破坏性重建
  • 调试注意事项:Android Studio调试时,不要勾选"Clear app data"选项,否则会清除已有数据库,重新触发预填充逻辑。若需重置数据库,可手动卸载App后重新安装

内容的提问来源于stack exchange,提问作者user19539777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:12:51