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

借助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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:15:00