使用Gson序列化android.print.PrinterInfo返回空对象问题求助
解决Gson序列化android.print.PrinterInfo返回空对象的问题
问题原因
android.print.PrinterInfo是Android系统内置类,它的核心数据字段大多为私有访问权限,且未暴露对应的公共getter方法。Gson默认依赖字段可见性或标准getter识别可序列化内容,因此无法自动读取这些私有字段,最终输出空对象。
解决方案:自定义TypeAdapter手动序列化
通过自定义TypeAdapter,利用反射获取PrinterInfo的私有字段,手动完成序列化逻辑。
步骤1:实现PrinterInfoTypeAdapter
import android.print.PrinterInfo import com.google.gson.TypeAdapter import com.google.gson.stream.JsonReader import com.google.gson.stream.JsonWriter class PrinterInfoTypeAdapter : TypeAdapter<PrinterInfo>() { override fun write(out: JsonWriter, printerInfo: PrinterInfo) { out.beginObject() // 手动指定需要序列化的核心字段(避免遍历所有字段的兼容性问题) // 获取打印机ID val idField = PrinterInfo::class.java.getDeclaredField("mId") idField.isAccessible = true out.name("printer_id").value(idField.get(printerInfo) as String) // 获取打印机名称 val nameField = PrinterInfo::class.java.getDeclaredField("mName") nameField.isAccessible = true out.name("printer_name").value((nameField.get(printerInfo) as CharSequence).toString()) // 获取打印机状态并转换为可读名称 val statusField = PrinterInfo::class.java.getDeclaredField("mStatus") statusField.isAccessible = true val statusCode = statusField.get(printerInfo) as Int out.name("status_code").value(statusCode) out.name("status_name").value( when (statusCode) { PrinterInfo.STATUS_IDLE -> "IDLE" PrinterInfo.STATUS_BUSY -> "BUSY" PrinterInfo.STATUS_UNAVAILABLE -> "UNAVAILABLE" else -> "UNKNOWN" } ) // 可按需添加其他字段,如mDescription、mCapabilities等 out.endObject() } override fun read(`in`: JsonReader): PrinterInfo { // 若无需反序列化,直接抛出异常即可 throw UnsupportedOperationException("PrinterInfo deserialization is not supported") } }
步骤2:注册TypeAdapter到Gson
创建Gson实例时注册自定义Adapter,替换默认序列化逻辑:
import com.google.gson.GsonBuilder val gson = GsonBuilder() .registerTypeAdapter(PrinterInfo::class.java, PrinterInfoTypeAdapter()) .create()
步骤3:使用配置好的Gson序列化
修改原有代码,用自定义Gson实例完成序列化:
val data: PrinterInfo = // 你的PrinterInfo实例 val jsonWriter = JsonWriter(StringWriter()) jsonWriter.beginObject() jsonWriter.name(data.javaClass.name) // 直接用Gson写入JsonWriter,避免嵌套序列化字符串的问题 gson.toJson(data, PrinterInfo::class.java, jsonWriter) jsonWriter.endObject() val serializedResult = jsonWriter.toString() Log.d(TAG, serializedResult)
注意事项
- 反射依赖系统类的内部字段名,不同Android版本中
PrinterInfo的字段可能存在变动,建议针对目标版本测试兼容性。 - 若只需要特定字段,手动指定字段名比遍历所有字段更稳定,避免序列化不必要的内部数据。
内容的提问来源于stack exchange,提问作者Gábor
相关产品推荐
相关产品推荐

