Android Realm迁移已执行 启动仍报RealmMigrationNeededException异常
问题根因与修复方案
该报错本质是Realm检测到TransactionData类的retriedOnExpired字段已被修改为必填属性,但迁移操作未正确匹配该属性变更,常见失效场景及修复方式如下:
- 迁移逻辑未显式指定必填属性
新增字段时Realm默认设置为可选属性,若模型类中该字段为非空类型,需在迁移代码中显式声明必填属性,示例如下:
// 错误写法:默认字段为可选,与模型类属性不匹配 realmSchema.get("TransactionData").addField("retriedOnExpired", boolean.class); // 正确写法:显式指定必填属性 realmSchema.get("TransactionData").addField("retriedOnExpired", boolean.class, FieldAttribute.REQUIRED);
如果是将已有可选字段修改为必填,需先补全所有旧数据的空值再修改属性:
realmSchema.get("TransactionData") // 先把所有null值替换为默认值 .transform(obj -> { if (obj.isNull("retriedOnExpired")) { obj.set("retriedOnExpired", false); } }) // 再设置为必填属性 .setNullable("retriedOnExpired", false);
Schema版本号未递增
每次修改模型结构后,必须将RealmConfiguration中的schemaVersion参数至少+1,Realm依靠版本号判断是否需要应用迁移逻辑,未升级版本号会导致迁移代码执行后仍被判定为未迁移。旧Realm实例未完全关闭
如果执行迁移前有其他未关闭的旧版本Realm实例,会导致迁移修改无法持久化到数据库,执行迁移前需确保所有已打开的Realm实例都已调用close()方法释放。
验证步骤
- 卸载测试设备上的现有App,先安装旧版本APK构造存量数据场景,再覆盖安装新版本APK测试
- 断点调试迁移代码执行完成后,调用
realmSchema.get("TransactionData").getField("retriedOnExpired").isRequired(),确认返回值为true
内容的提问来源于stack exchange,提问作者htafoya
相关产品推荐
相关产品推荐

