添加Date类型TypeConverter后Room无法存储API返回结果
问题核心原因及修复方案
你遇到的问题由三个常见的低级错误共同导致,按优先级修复即可:
1. 日期格式符使用错误
你代码里的SimpleDateFormat用了YYYY模式符,这是JDK定义的周年计算规则,和日常使用的公历年逻辑完全不同,大概率会解析失败返回null,需要替换为小写的yyyy,同时建议指定时区和Locale避免多设备适配问题:
import androidx.room.TypeConverter import java.text.ParseException import java.text.SimpleDateFormat import java.util.* class Converters { // 固定格式与时区,避免不同设备解析差异 private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).apply { timeZone = TimeZone.getTimeZone("GMT+8") // 替换为你接口对应的时区 } @TypeConverter fun fromTimestampStr(timeStamp: String?): Date? { return timeStamp?.let { try { dateFormat.parse(it) } catch (e: ParseException) { e.printStackTrace() null } } } @TypeConverter fun toTimestampStr(date: Date?): String? { return date?.let { dateFormat.format(it) } } }
2. Gson未配置日期解析适配器
你之前用String?类型的时候API返回的字符串可以直接被Gson解析,改为Date?类型后,Gson默认没有内置对应格式的字符串转Date的适配器,API返回数据解析阶段dateAdded就已经是null了,不是Room不存,是你要存的对象本身该字段就为空。
在构造Retrofit的Gson转换器时添加日期格式配置即可:
val gson = GsonBuilder() .setDateFormat("yyyy-MM-dd HH:mm:ss") .create() val retrofit = Retrofit.Builder() .baseUrl(你的接口根地址) .addConverterFactory(GsonConverterFactory.create(gson)) // 其他配置 .build()
3. 数据库结构变更未升级版本
你修改了表字段类型后,数据库版本号仍为1,如果你的设备上之前已经安装过旧版应用、存在旧数据库文件,Room检测到结构不匹配又没有迁移规则时会静默写入失败。
开发阶段可以直接升级版本号加销毁重建配置,避免迁移麻烦:
// 数据库版本号从1改为2 @Database( entities = arrayOf( Cocktail::class, CocktailRecipe::class, CocktailIngredient::class, IngredientType::class, Lists::class, ListsDrinksItems::class ), version = 2, exportSchema = false ) @TypeConverters(Converters::class) abstract class GoodCallDatabase : RoomDatabase() { // 原有逻辑不变 private fun buildDatabase(context: Context) = Room.databaseBuilder( context.applicationContext, GoodCallDatabase::class.java, "goodcalldatabase.db" ) .fallbackToDestructiveMigration() // 开发阶段加这行,结构变更直接清空旧数据库重建 .build() }
验证方法
修复后在调用DAO存入Cocktail对象前打个断点,确认dateAdded字段已经被正确解析为非null的Date对象即可。
内容的提问来源于stack exchange,提问作者JBuser
相关产品推荐
相关产品推荐

