借助Hilt实现从JSON预填充Room Database时数据为空问题求助
问题排查与解决方案
1. 回调未触发(最常见原因)
Room的onCreate回调仅在数据库第一次创建时执行,若此前运行过App生成了数据库文件,后续修改代码不会重新触发该回调。
解决方法:
- 卸载设备上的原有App后重新安装,彻底清除旧数据库文件
- 或者将
@Database注解中的version值+1,配合你已配置的fallbackToDestructiveMigration,触发数据库销毁重建
2. 协程执行异常
你定义的全局协程Scope仅配置了SupervisorJob(),未指定调度器,默认使用Dispatchers.Default,虽然Room挂起函数会自动调度,但极端情况下可能出现协程意外取消的问题。
修改AppModule中协程Scope的配置:
@ApplicationScope @Provides @Singleton fun provideApplicationScope() = CoroutineScope(SupervisorJob() + Dispatchers.IO)
也可以在启动协程时显式指定调度器:
applicationScope.launch(Dispatchers.IO) { prePopulateDatabase(climbingRouteDao) }
3. JSON解析异常
如果JSON文件字段与ClimbingRoute实体类字段不匹配、JSON格式错误,Gson会解析出空列表,插入后数据库自然为空。
排查方法:在prePopulateDatabase方法中添加日志,验证解析结果:
val boulderClimbingRoutes = Gson().fromJson<List<ClimbingRoute>>(jsonString, typeToken) // 加日志验证 Log.d("PrePopulate", "解析到的线路数量:${boulderClimbingRoutes.size}")
如果数量为0,检查ClimbingRoute实体类的字段名、类型是否和JSON完全一致,或者添加@SerializedName注解显式指定JSON字段名。
4. 插入策略跳过数据
你的DAO插入方法使用OnConflictStrategy.IGNORE,如果ClimbingRoute的主键存在重复、或者主键值不符合约束,插入操作会被静默忽略。
排查方法:
- 确认
ClimbingRoute的主键配置,如果主键是autoGenerate = true,不要手动指定主键值为固定值 - 临时将插入策略改为
OnConflictStrategy.REPLACE验证是否是冲突导致的插入失败
5. 资源读取异常
如果R.raw.climbing_routes文件不存在、或者放置在错误的资源限定符文件夹下,会导致读取到的JSON字符串为空。
排查方法:在读取JSON后添加日志验证内容:
val jsonString = resources.openRawResource(R.raw.climbing_routes).bufferedReader().use { it.readText() } Log.d("PrePopulate", "读取到的JSON内容:$jsonString")
内容的提问来源于stack exchange,提问作者tommybomb
相关产品推荐
相关产品推荐

