You need to enable JavaScript to run this app. Android应用通过Retrofit2调用API接收ByteArray时报错如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Android应用通过Retrofit2调用API接收ByteArray时报错如何解决

报错原因

你当前的Retrofit全局配置了GsonConverterFactory,Gson会默认将所有接口的返回内容都当做JSON格式解析,而你请求的图片接口返回的是二进制字节流,不符合JSON格式要求,两次报错本质都是Gson解析二进制内容失败导致的:

  • 第一次指定Response<ByteArray>时,Gson尝试将返回内容解析为JSON数组,找不到JSON数组的起始标识[,所以抛出Expected BEGIN_ARRAY but was STRING异常
  • 第二次修改为Response<String>时,Gson尝试将返回内容解析为JSON字符串,二进制内容不符合JSON语法规则,所以抛出MalformedJsonException异常

解决方案

方案1:用ResponseBody接收二进制流(推荐)

直接使用OkHttp原生的ResponseBody接收二进制数据,不需要经过Gson解析,步骤如下:

  1. 修改API接口,添加@Streaming注解,响应类型改为Response<ResponseBody>:
@Streaming // 大文件建议加此注解,避免一次性全量加载进内存
@GET("api/getImage")
suspend fun getImage(@Query("user_id") user_id: String): Response<ResponseBody>
  1. 在Repository层从ResponseBody中取出字节数组:
suspend fun getImage(user_id: String): ByteArray? {
    val response = RetrofitInstance.api.getImage(user_id)
    return if (response.isSuccessful) {
        response.body()?.bytes()
    } else {
        // 可自行添加请求失败的处理逻辑
        null
    }
}

方案2:配置多ConverterFactory(适合同一个Retrofit实例同时对接JSON接口和二进制接口的场景)

在构建Retrofit实例时,先添加ScalarsConverterFactory再添加GsonConverterFactory,让非JSON格式的响应优先被Scalars转换器处理:

  1. 先引入Scalars转换器依赖(build.gradle):
implementation "com.squareup.retrofit2:converter-scalars:2.9.0" // 版本和你Retrofit版本保持一致即可
  1. 修改Retrofit配置:
private val retrofit by lazy {
    val gson = GsonBuilder().setLenient().create()
    Retrofit.Builder()
        .baseUrl(BASE_URL)
        .client(client)
        .addConverterFactory(ScalarsConverterFactory.create()) // 排在Gson前面
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build()
}

修改后你之前声明Response<String>的写法也可以正常运行,拿到字符串后自行转成字节数组即可。


内容的提问来源于stack exchange,提问作者coderperz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 00:15:04