Room DB Gson TypeConverter报错:无法创建NumberFormat实例
问题原因及解决方案
崩溃根源
你的崩溃是因为DataPatientPhotoTaken类中包含了Gson无法默认序列化/反序列化的类型,具体是SimpleDateFormat和Bitmap,其中SimpleDateFormat的问题直接触发了日志中的NumberFormat实例创建异常:
java.lang.RuntimeException: Unable to create instance of class java.text.NumberFormat...
具体原因分析
- SimpleDateFormat的问题:它是带状态的日期格式化工具类,没有无参构造方法,且内部依赖
NumberFormat等复杂成员。Gson默认通过反射实例化对象时,无法处理这种没有无参构造、内部状态复杂的类,尝试创建其依赖的NumberFormat时失败,抛出异常。 - Bitmap的问题:Bitmap是Android原生的图片资源对象,本身不适合直接序列化存储,Gson也没有默认的适配器处理它,直接存储会导致数据损坏或反序列化失败。
解决方案
替换SimpleDateFormat为可序列化的日期类型
不要直接存储SimpleDateFormat对象,改用String存储格式化后的日期字符串,或者用Long存储时间戳,Gson可以直接处理这两种类型:data class DataPatientPhotoTaken( val dateTime: String, // 比如"yyyy-MM-dd HH:mm:ss"格式的字符串 // 或者用Long存储时间戳:val dateTime: Long var hasBeenUploadedRedcap: Boolean = false, val focusPoint: String, // 后续处理Bitmap的替换 ): Serializable当需要使用日期格式化时,再从字符串/时间戳转换为
SimpleDateFormat实例。替换Bitmap为可序列化的格式
不要直接存储Bitmap对象,将其转换为Base64字符串或字节数组存储,反序列化时再转回Bitmap:data class DataPatientPhotoTaken( val dateTime: String, var hasBeenUploadedRedcap: Boolean = false, val focusPoint: String, val bitmapBase64: String // 存储Bitmap的Base64字符串 ): Serializable转换示例代码:
// Bitmap转Base64 fun bitmapToBase64(bitmap: Bitmap): String { val outputStream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream) val byteArray = outputStream.toByteArray() return Base64.encodeToString(byteArray, Base64.DEFAULT) } // Base64转Bitmap fun base64ToBitmap(base64: String): Bitmap { val byteArray = Base64.decode(base64, Base64.DEFAULT) return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size) }确保数据类仅包含纯数据类型
用于Room存储和Gson序列化的数据类,应只包含基本类型、字符串、集合或自定义纯数据类,避免包含Android原生组件(如Bitmap)、带状态的工具类(如SimpleDateFormat)这类无法被Gson默认处理的类型。
内容的提问来源于stack exchange,提问作者DoctorWho
相关产品推荐
相关产品推荐

