You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:42:43