图片应用添加离线缓存时出现Moshi解析错误:期望对象却收到数组
解决Moshi解析错误:Expected BEGIN_OBJECT but was BEGIN_ARRAY at path $
问题根源
Picsum Photos API返回的是JSON数组(直接包含图片对象集合),但你的Retrofit接口方法getImages()定义为返回NetworkImageContainer类型(一个封装了images列表的外层对象)。Moshi尝试将数组解析为对象时,类型完全不匹配,因此抛出Expected BEGIN_OBJECT but was BEGIN_ARRAY错误。
修复步骤
- 调整Retrofit接口返回类型:让接口直接返回图片对象的列表,而非外层容器
- 修改数据转换逻辑:针对
List<NetworkImage>编写扩展转换函数,替代原有的NetworkImageContainer转换方法
修改后的代码
Retrofit接口部分
interface ImageApiService { @GET("v2/list") suspend fun getImages(): List<NetworkImage> // 改为返回List<NetworkImage> }
数据类与转换函数部分
import com.example.images.database.DatabaseImages import com.example.images.domain.ImagesModels import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class NetworkImage( val id: String, val author: String, @Json(name = "download_url") val download_url: String ) // 移除不再需要的NetworkImageContainer,或保留但不再用于接口解析 // @JsonClass(generateAdapter = true) // data class NetworkImageContainer(val images:List<NetworkImage>) // 直接为List<NetworkImage>编写转换扩展 fun List<NetworkImage>.asDomainModel(): List<ImagesModels> { return map { ImagesModels( id = it.id, author = it.author, download_url = it.download_url ) } } fun List<NetworkImage>.asDatabaseModel(): List<DatabaseImages>{ return map { DatabaseImages( id = it.id, author = it.author, download_url = it.download_url ) } }
调用逻辑调整
原调用逻辑:
val container = ImageApiNet.retrofitService.getImages() val domainModels = container.asDomainModel()
修改后:
val networkImages = ImageApiNet.retrofitService.getImages() val domainModels = networkImages.asDomainModel()
原理说明
Moshi原生支持将JSON数组解析为Kotlin的List类型,直接让接口返回List<NetworkImage>,就能和API返回的JSON结构完全匹配,彻底解决类型不匹配的解析错误。
内容的提问来源于stack exchange,提问作者Abdulaziz Alhobayyeb
相关产品推荐
相关产品推荐

