Retrofit+Moshi返回Flow类型报无JsonAdapter异常排查
问题根因
抛出java.lang.IllegalArgumentException: 无法为kotlinx.coroutines.flow.Flow<PokemonResponse>创建响应转换器的核心原因是:
- Retrofit默认不识别接口方法声明的
Flow返回类型,你当前仅为Retrofit注册了Moshi序列化转换器,该转换器只会尝试将HTTP响应体解析为JSON实体类,无法处理Flow这种协程数据流类型,因此会抛出找不到对应JsonAdapter的异常。 - 你之前尝试将返回类型改为
Flow<Response<PokemonResponse>>没有效果,是因为返回类型的最外层依然是Flow,Moshi转换器依然会优先尝试匹配Flow的解析适配器,问题本质没有变化。
修复步骤
- 第一步:补充Retrofit对协程类型的适配依赖。在模块级
build.gradle的dependencies块中添加协程适配器依赖,注意该依赖的版本号必须和你当前引入的Retrofit核心库版本完全一致,避免版本冲突:implementation "com.squareup.retrofit2:adapter-kotlin-coroutines:和本地Retrofit一致的版本号" - 第二步:修改Hilt中提供Retrofit实例的代码,在Retrofit构建流程中除了添加Moshi转换器工厂,还要注册协程调用适配器工厂,否则Retrofit依然无法识别协程相关返回类型:
@Provides @Singleton fun provideRetrofit(moshi: Moshi, okHttpClient: OkHttpClient): Retrofit { return Retrofit.Builder() .baseUrl(你的接口基地址) .addConverterFactory(MoshiConverterFactory.create(moshi)) // 必须添加下面这行,注册协程适配器 .addCallAdapterFactory(CoroutinesResponseCallAdapterFactory.create()) .client(okHttpClient) .build() }
- 第三步:修正
PokemonApiService的接口声明,不要在接口方法层直接返回Flow类型。Retrofit的协程适配器只对挂起函数做转换,正确写法有两种:- 不需要处理HTTP状态码时,直接返回实体类:
interface PokemonApiService { @GET("pokemon接口路径") suspend fun getPokemonList(): PokemonResponse }- 需要获取HTTP状态码、请求头等信息时,包一层Retrofit自带的Response:
如果你业务层确实需要使用Flow做数据流转,不要把Flow声明在ApiService接口层,而是在RemoteDataSource或者Repository层,通过flow构造块包装挂起请求的返回结果即可:interface PokemonApiService { @GET("pokemon接口路径") suspend fun getPokemonList(): Response<PokemonResponse> }// RemoteDataSource层示例 fun getPokemonList(): Flow<Result<PokemonResponse>> = flow { try { val data = apiService.getPokemonList() emit(Result.success(data)) } catch (e: Exception) { emit(Result.failure(e)) } }.flowOn(Dispatchers.IO)
常见无效操作避坑
- 不要尝试为Moshi自定义Flow类型的JsonAdapter:JsonAdapter的职责是完成JSON字符串和Kotlin数据类的互相转换,Flow是协程层的数据流抽象,和JSON解析逻辑完全无关,自定义JsonAdapter属于方向错误,完全解决不了问题。
- 不要混用不同版本的Retrofit组件:Retrofit核心库、Moshi转换器、协程适配器必须使用完全一致的版本号,版本不匹配会导致适配器注册失效,依然会抛出类型转换异常。
- 不要使用已经停止维护的第三方Retrofit协程适配库,这类库对新版本Kotlin协程、Flow的兼容性存在已知问题,直接使用Retrofit官方提供的协程适配器即可。
内容的提问来源于stack exchange,提问作者Dr Mido
相关产品推荐
相关产品推荐

