为现有Android项目添加KMM支持后Room数据库异常
问题描述
在现有Android项目中新增KMM共享模块,仅添加了一个简单类和GraphQL查询,未修改任何Room实体或数据库配置,但从旧版本应用更新到新版本时,出现Room报错:
Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
使用的KMM相关依赖如下:
api("com.apollographql.apollo3:apollo-runtime:3.7.4") api("com.badoo.reaktive:reaktive:$reaktiveVersion") api("com.badoo.reaktive:coroutines-interop:$reaktiveVersion") implementation("com.russhwolf:multiplatform-settings-no-arg:$multiplatformSettings")
可能的原因
虽然你没手动修改Room实体,但KMM依赖可能间接干扰了Room的schema生成逻辑:
- Apollo3注解处理器冲突:Apollo的注解处理器在字节码处理阶段可能和Room的处理器产生交互,导致Room生成的schema哈希值变化。Room靠编译时生成的schema哈希和运行时数据库的哈希比对来验证完整性,哪怕实体代码没改,只要哈希变了就会触发错误。
- Multiplatform Settings的no-arg影响:
multiplatform-settings-no-arg会为类生成无参构造函数,如果你的Room实体或相关类被这个处理器意外修改了字节码,会导致Room的schema计算发生变化。 - KMM模块改变编译环境:KMM模块的加入可能修改了项目的类路径或编译参数,让Room编译时扫描到额外的类(比如KMM模块中的类),哪怕这些不是Room实体,也可能干扰schema生成流程。
解决方案
快速修复:提升Room数据库版本
直接在Room数据库类中增加版本号,若不需要修改表结构,可添加空迁移:@Database(entities = [YourEntity::class], version = 2) // 版本号+1 abstract class AppDatabase : RoomDatabase() { // ... }若数据不重要,也可以用
fallbackToDestructiveMigration()跳过迁移,但会清空数据库。排查并隔离KMM依赖影响
- 限定Apollo3处理范围:在模块
build.gradle中配置Apollo只处理指定目录下的GraphQL文件,避免扫描Room实体:apollo { service("default") { sourceFolder.set("graphql") // 指定你的GraphQL文件存放目录 } } - 控制no-arg作用范围:如果Room实体已有合适构造函数,尝试移除
multiplatform-settings-no-arg,或者配置它只作用于特定类/包:noArg { annotation("com.yourpackage.YourCustomNoArgAnnotation") // 仅给带该注解的类生成无参构造 } - 清理编译缓存:执行
./gradlew clean build,清除旧编译产物,确保Room生成的schema是最新的。
- 限定Apollo3处理范围:在模块
验证schema哈希变化
找到编译生成的RoomMasterTable.java(路径:app/build/generated/source/room/<variant>/<你的包名>/RoomMasterTable.java),对比新旧版本的哈希值,确认是否是哈希变化导致的错误。
内容的提问来源于stack exchange,提问作者AndreiBogdan
相关产品推荐
相关产品推荐

