Room中多TypeConverter失效:CompressConverter未生成问题求助
问题原因
Room 原生支持 String 类型的持久化,会直接将其映射为数据库的 TEXT 类型。你的 Item 类中 img 字段是 String?,Room 无需任何转换就能直接存储,因此不会触发 CompressConverter 中的方法,看起来就像转换器没生成。
而 CategoriesConverter 能生效,是因为 List<String> 是 Room 不直接支持的类型,必须转换为 Room 支持的 String 才能存储,所以 Room 会主动调用该转换器。
解决方案
如果你确实需要将字符串以字节数组的形式存储(比如需要自定义压缩逻辑),可以按以下步骤调整:
修改实体类字段类型
将img字段的类型改为ByteArray?,让 Room 将其映射为数据库的BLOB类型:@Entity(tableName = "items") data class Item( val img: ByteArray? = null, // 改为ByteArray类型 @TypeConverters(CategoriesConverter::class) val categories: List<String> = listOf() )调整转换器逻辑(可选,若需自动转换String与ByteArray)
如果想在业务代码中直接使用String而非ByteArray,可以创建自定义类型,再通过转换器处理它与ByteArray的互转(还能加入GZIP等压缩逻辑):// 自定义类型 @JvmInline value class CompressedString(val value: String) @ProvidedTypeConverter class CompressConverter { @TypeConverter fun fromCompressedString(value: CompressedString?): ByteArray? { return value?.value?.toByteArray(Charsets.UTF_8) } @TypeConverter fun toCompressedString(data: ByteArray?): CompressedString? { return data?.let { CompressedString(String(it, Charsets.UTF_8)) } } }同步修改实体类字段:
@Entity(tableName = "items") data class Item( @TypeConverters(CompressConverter::class) val img: CompressedString? = null, @TypeConverters(CategoriesConverter::class) val categories: List<String> = listOf() )简化转换器标注
既然已经在@Database注解中声明了所有转换器,无需在实体类字段上重复标注,统一简化为:@TypeConverters(CategoriesConverter::class, CompressConverter::class) @Database( entities = [Item::class], version = 1, exportSchema = false ) abstract class AppDatabase : RoomDatabase() @Entity(tableName = "items") data class Item( val img: CompressedString? = null, // 或ByteArray? val categories: List<String> = listOf() )
内容的提问来源于stack exchange,提问作者Psijic
相关产品推荐
相关产品推荐

