无法为retrofit2.Response<...>创建调用适配器。

22

我的API:

@GET("/cinema/notShownMovies")
fun getNotShownMovies(
   @Query("token") token: String
): Response<GetMovieResponse>

调用API时出现异常:

java.lang.IllegalArgumentException: 无法为方法InstanceApi.getNotShownMovies中的retrofit2.Response<...data.GetMovieResponse>创建调用适配器,可能是模型错误导致。

我不知道从哪里开始。其他所有在相同API类中定义的API调用都正常工作。也许是模型错误?


你如何创建ApiService? - Hello World
你的服务中其他可用的方法是包装在 Response<> 或者 Call<> 中的吗? - Saurabh Thorat
val retrofit = Retrofit.Builder() .client(client) .baseUrl(url) .addConverterFactory(MoshiConverterFactory.create()) .build() return retrofit.create(Api::class.java) - kaulex
所有方法都被包装在 Response<> 中。 - kaulex
另外,为什么你要使用 Response<GetMovieResponse> 而不是 Response<Movie> - Abdul Mateen
3个回答

59

如果使用了协程,请添加suspend修饰符。这将解决问题。

否则,您的问题可能是因为在实例化Retrofit对象时没有添加调用适配器。 例如,对于RxJava2,您可以在构建时添加此行来包含调用适配器。

.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))

8
如果你正在使用协程,那么在你的函数前面加上关键字suspend。我还相信你只需要将你的数据类包装在Response中即可。 - Abdul Mateen
2
是的,这个错误信息对于识别缺少suspend并没有什么帮助。 - Abdul Mateen
1
这个API缺少暂停功能,非常感谢。 - Nguyen
2
非常感谢,我已经尝试了一整天,但是API函数缺少Suspend - Suhad Bin Zubair
2
@SuhadBinZubair 我之前也遇到了同样的问题,就是在Retrofit API调用中缺少了suspend。加上之后就完美解决了。 - JPM
显示剩余3条评论

15

我遇到了类似的崩溃 IllegalArgumentException: Call return type must be parameterized as Call

崩溃日志:

Caused by: java.lang.IllegalArgumentException: Unable to create call adapter for interface retrofit2.Call
    for method Api.login
    at retrofit2.Utils.methodError(Utils.java:54)
    at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:116)
    at retrofit2.HttpServiceMethod.parseAnnotations(HttpServiceMethod.java:67)
    at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:39)
    at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:202)
    at retrofit2.Retrofit$1.invoke(Retrofit.java:160)
    at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
    at $Proxy0.login(Unknown Source)
    at <redacted>.screen.login.LoginActivity.onSignInClick(LoginActivity.java:103)
    ... 13 more
Caused by: java.lang.IllegalArgumentException: Call return type must be parameterized as Call<Foo> or Call<? extends Foo>
    at retrofit2.DefaultCallAdapterFactory.get(DefaultCallAdapterFactory.java:42)
    at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:253)
    at retrofit2.Retrofit.callAdapter(Retrofit.java:237)
    at retrofit2.HttpServiceMethod.createCallAdapter(HttpServiceMethod.java:114)
    ... 20 more

我发现它崩溃是因为Proguard/R8。Proguard正在重命名Retrofit类,为了解决这个问题,我更新了Proguard设置:
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }

它确实解决了崩溃的问题,但是我开始遇到适配器的问题。例如,我看到同一项多次显示。 - Arpit
它解决了 :) 去年十二月更新应用后,我那时候没有遇到这个问题。今天我需要添加两个 Progard 规则。不知道为什么? - M DEV
@Arpit 我遇到了同样的问题,物品显示了多次。你是怎么解决的? - Dayem Saeed
1
有一些Proguard规则需要为gson定义。@DayemSaeed,请检查一下。 - Arpit
1
我的proguard-rules文件中有retrofit规则,但没有2,你的评论救了我一命。这么一个小细节给我带来了这么多麻烦... - Ícaro

-3
在Gradle文件中,在release buildTypes内添加以下行:
  • minifyEnabled false

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心找到有关如何编写良好答案的更多信息。 - abdo Salm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接