本文介绍了改造2.6.0异常:java.lang.IllegalArgumentException:无法为kotlinx.coroutines.Deferred创建调用适配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Kotlin协程和改造项目.

I have a project with Kotlin coroutines and Retrofit.

我有这些依赖项:

implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'

今天,我已将项目中的改造更新为 2.6.0 .在 https://github.com/JakeWharton/retrofit2-kotlin-coroutines-adapter记录现在不推荐使用.在 https://github.com/square/retrofit/blob/master/CHANGELOG.md#version-260-2019-06-05 据记载,Retrofit当前支持suspend.

Today I have updated Retrofit to 2.6.0 in the project. In https://github.com/JakeWharton/retrofit2-kotlin-coroutines-adapter it is written that it is deprecated now. In https://github.com/square/retrofit/blob/master/CHANGELOG.md#version-260-2019-06-05 it is written that Retrofit currently supports suspend.

因此,我删除了retrofit2-kotlin-coroutines-adapter:0.9.2,并在Retrofit客户端中更改了以下几行:

So, I removed retrofit2-kotlin-coroutines-adapter:0.9.2 and in Retrofit client changed these lines:

        retrofit = Retrofit.Builder()
            .baseUrl(SERVER_URL)
            .client(okHttpClient)
            .addConverterFactory(MyGsonFactory.create(gson))
            //.addCallAdapterFactory(CoroutineCallAdapterFactory()) - removed it.
            .build()

运行时,第一个请求捕获一个异常:

When run, the first request catches an exception:

java.lang.IllegalArgumentException: Unable to create call adapter for kotlinx.coroutines.Deferred<com.package.model.response.UserInfoResponse>
    for method Api.getUserInfo

据我了解,我可以使用CallAdapter.Factory()代替CoroutineCallAdapterFactory(),但这是抽象的.

As I understood, instead of CoroutineCallAdapterFactory() I could use CallAdapter.Factory(), but it is abstract.

如果在Api类中,我更改了在开头添加suspend的请求:

If in Api class I change a request adding suspend in the beginning:

@FormUrlEncoded
@POST("user/info/")
suspend fun getUserInfo(@Field("token") token: String): Deferred<UserInfoResponse>

override suspend fun getUserInfo(token: String): Deferred<UserInfoResponse> =
    service.getUserInfo(token)

我收到此异常:

java.lang.RuntimeException: Unable to invoke no-args constructor for kotlinx.coroutines.Deferred<com.package.model.response.UserInfoResponse>. Registering an InstanceCreator with Gson for this type may fix this problem.

推荐答案

阅读 https://github.com/square/retrofit/blob/master/CHANGELOG.md#version-260-2019-06-05 我看到了:

@GET("users/{id}")暂停有趣的用户(@Path("id")长id):用户

@GET("users/{id}") suspend fun user(@Path("id") long id): User

在幕后的行为就像定义为好玩的用户(...): 调用,然后使用Call.enqueue进行调用.您也可以返回 用于访问响应元数据的响应.

Behind the scenes this behaves as if defined as fun user(...): Call and then invoked with Call.enqueue. You can also return Response for access to the response metadata.

当前,此集成仅支持非null响应主体类型. 请遵循问题3075,以获取可空类型支持.

Currently this integration only supports non-null response body types. Follow issue 3075 for nullable type support.

我更改了请求,因此:添加了suspend并删除了Deferred:

I changed requests so: added suspend and removed Deferred:

@FormUrlEncoded
@POST("user/info/")
suspend fun getUserInfo(@Field("token") token: String): UserInfoResponse


override suspend fun getUserInfo(token: String): UserInfoResponse =
    service.getUserInfo(token)

然后在交互器中(或只是在调用方法getUserInfo(token)时)将await()删除:

Then in interactor (or simply when called the method getUserInfo(token)) removed await():

override suspend fun getUserInfo(token: String): UserInfoResponse =
    // api.getUserInfo(token).await() - was before.
    api.getUserInfo(token)

更新

我在下载PDF文件时遇到一种情况,需要删除Api类中的suspend.请参阅如何使用Retrofit和Kotlin协程下载PDF文件? .

Once I encountered a situation when downloading PDF files required removing suspend in Api class. See How to download PDF file with Retrofit and Kotlin coroutines?.

这篇关于改造2.6.0异常:java.lang.IllegalArgumentException:无法为kotlinx.coroutines.Deferred创建调用适配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 12:41