如何将List<List<Bitmap>>保存至Room数据库?类型转换器添加方法
解决Room数据库中List<List>的类型转换器问题
Room默认不支持直接存储嵌套的Bitmap列表,需要自定义类型转换器,将List<List<Bitmap>>与数据库兼容的ByteArray进行双向转换,具体实现步骤如下:
1. 创建类型转换器类
编写包含双向转换逻辑的工具类,先将嵌套Bitmap列表转为嵌套ByteArray列表,再序列化整体为ByteArray;读取时反向操作,将ByteArray转回嵌套Bitmap列表:
class BitmapListConverter { @TypeConverter fun fromBitmapList(bitmapList: List<List<Bitmap>>?): ByteArray? { if (bitmapList == null) return null return try { val byteArrayOutputStream = ByteArrayOutputStream() val objectOutputStream = ObjectOutputStream(byteArrayOutputStream) // 逐个将Bitmap转为ByteArray val nestedByteArrays = bitmapList.map { innerList -> innerList.map { bitmap -> val baos = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos) baos.toByteArray() } } objectOutputStream.writeObject(nestedByteArrays) objectOutputStream.flush() byteArrayOutputStream.toByteArray() } catch (e: IOException) { e.printStackTrace() null } } @TypeConverter fun toBitmapList(byteArray: ByteArray?): List<List<Bitmap>>? { if (byteArray == null) return null return try { val byteArrayInputStream = ByteArrayInputStream(byteArray) val objectInputStream = ObjectInputStream(byteArrayInputStream) @Suppress("UNCHECKED_CAST") val nestedByteArrays = objectInputStream.readObject() as List<List<ByteArray>> // 逐个将ByteArray转回Bitmap nestedByteArrays.map { innerList -> innerList.map { byteArr -> BitmapFactory.decodeByteArray(byteArr, 0, byteArr.size) } } } catch (e: IOException | ClassNotFoundException) { e.printStackTrace() null } } }
2. 为Room数据库注册转换器
在你的Room数据库类上添加@TypeConverters注解,指定刚创建的转换器类,让Room识别并使用该转换规则:
@Database(entities = [Item::class], version = 1) @TypeConverters(BitmapListConverter::class) abstract class AppDatabase : RoomDatabase() { abstract fun itemDao(): ItemDao }
注意事项
- 压缩格式选择:示例中使用
PNG无损压缩,若追求更小体积可改用JPEG并调整压缩质量(第二个参数0-100)。 - 性能与存储:直接存储Bitmap字节数组会占用较多数据库空间,若图片数量多、尺寸大,建议将图片保存到文件系统,仅在数据库中存储文件路径,更高效。
内容的提问来源于stack exchange,提问作者Jorpy
相关产品推荐
相关产品推荐

