无法为类example.Simple创建调用适配器

rmu*_*ler 67 java rest simple-framework retrofit

我正在使用SimpleXml改装2.0.0-beta1.我想从REST服务中检索一个简单(XML)资源.使用SimpleXML编组/解组Simple对象可以正常工作.

使用此代码时(转换后的2.0.0代码形式):

final Retrofit rest = new Retrofit.Builder()
    .addConverterFactory(SimpleXmlConverterFactory.create())
    .baseUrl(endpoint)
    .build();
SimpleService service = rest.create(SimpleService.class);
LOG.info(service.getSimple("572642"));
Run Code Online (Sandbox Code Playgroud)

服务:

public interface SimpleService {

    @GET("/simple/{id}")
    Simple getSimple(@Path("id") String id);

}
Run Code Online (Sandbox Code Playgroud)

我得到这个例外:

Exception in thread "main" java.lang.IllegalArgumentException: Unable to create call adapter for class example.Simple
    for method SimpleService.getSimple
    at retrofit.Utils.methodError(Utils.java:201)
    at retrofit.MethodHandler.createCallAdapter(MethodHandler.java:51)
    at retrofit.MethodHandler.create(MethodHandler.java:30)
    at retrofit.Retrofit.loadMethodHandler(Retrofit.java:138)
    at retrofit.Retrofit$1.invoke(Retrofit.java:127)
    at com.sun.proxy.$Proxy0.getSimple(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

我错过了什么?我知道通过Call作品包装返回类型.但是我希望服务将业务对象作为类型返回(并在同步模式下工作).

UPDATE

添加额外的依赖项后,并.addCallAdapterFactory(RxJavaCallAdapterFactory.create())根据不同的答案建议,我仍然会收到此错误:

Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried:
 * retrofit.RxJavaCallAdapterFactory
 * retrofit.DefaultCallAdapter$1
Run Code Online (Sandbox Code Playgroud)

cha*_*nin 188

Kotlin协程的情况下,这种情况发生在我忘记将 api 服务函数标记为suspend我从CoroutineScope(Dispatchers.IO).launch{}以下位置调用此函数时:

用法:

    val apiService = RetrofitFactory.makeRetrofitService()

    CoroutineScope(Dispatchers.IO).launch {

        val response = apiService.myGetRequest()

        // process response...

    }
Run Code Online (Sandbox Code Playgroud)

接口服务.kt

interface ApiService {

       @GET("/my-get-request")
       suspend fun myGetRequest(): Response<String>
}
Run Code Online (Sandbox Code Playgroud)

  • 你救了我的命兄弟s2 (2认同)
  • 就我而言,这个错误是因为我忘记在服务标记中暂停我们的功能。感谢您的回答。:) (2认同)

Hos*_*Aly 55

简答:Call<Simple>在您的服务界面中返回.

看起来Retrofit 2.0正试图找到一种为服务接口创建代理对象的方法.它希望你写这个:

public interface SimpleService {
    @GET("/simple/{id}")
    Call<Simple> getSimple(@Path("id") String id);
}
Run Code Online (Sandbox Code Playgroud)

但是,当你不想回归时,它仍然希望发挥出色并且灵活Call.为了支持这一点,它具有a的概念CallAdapter,它应该知道如何适应Call<Simple>a Simple.

使用RxJavaCallAdapterFactory仅在您尝试返回时才有用rx.Observable<Simple>.

最简单的解决方案是返回a CallRetrofit所期望的.CallAdapter.Factory如果你真的需要它,你也可以写一个.

  • 是的,这确实是正确的答案:(。我从一开始就知道 `Call&lt;Simple&gt;` 是它的工作方式。但是,正如我的问题中所述,我的偏好是只返回 `Simple` (情况就是如此)在早期版本中)。我的结论是:没有额外的代码是不可能的。 (2认同)

shi*_*hui 52

添加依赖项:

compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'
Run Code Online (Sandbox Code Playgroud)

以这种方式创建适配器:

Retrofit rest = new Retrofit.Builder()
    .baseUrl(endpoint)
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .addConverterFactory(SimpleXmlConverterFactory.create())
    .build();
Run Code Online (Sandbox Code Playgroud)

addCallAdapterFactory ()并且addConverterFactory ()都需要被调用.

服务:

public interface SimpleService {

    @GET("/simple/{id}")
    Call<Simple> getSimple(@Path("id") String id);

}
Run Code Online (Sandbox Code Playgroud)

修改SimpleCall<Simple>.

  • 我知道改变Simple to Call <Simple>就可以了.但是,我不想在服务接口中引入类型`Call` (7认同)

Mer*_*ost 45

我将协程与CoroutineCallAdapterFactory一起使用,但不小心忘记了创建该函数suspend。希望它能帮助别人!


Him*_*ani 36

使用新的Retrofit(2. +),您需要添加addCallAdapterFactory(可以是普通的)或RxJavaCallAdapterFactory(对于Observables).我认为你可以添加更多.它会自动检查使用哪一个.请参阅下面的工作示例.您还可以查看此链接以获取更多详细信息.

 Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiConfig.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build()
Run Code Online (Sandbox Code Playgroud)

  • RxJavaCallAdapterFactory需要来自同一个repo的adapter-rxjava工件.```compile'c​​om.squareup.retrofit:adapter-rxjava:2.0.0-beta1'``` (5认同)
  • 对于retrofit2,请确保使用正确的依赖项`com.squareup.retrofit2:adapter-rxjava:2.1.0`和`com.squareup.retrofit2:converter-gson:2.1.0` (2认同)

小智 15

对于这种情况:

val apiService = RetrofitFactory.makeRetrofitService()

CoroutineScope(Dispatchers.IO).launch {

    val response = apiService.myGetRequest()

    // process response...

}

interface ApiService {

   @GET("/my-get-request")
   suspend fun myGetRequest(): Response<String>
}
Run Code Online (Sandbox Code Playgroud)

函数内使用的所有方法都 suspend必须标记为,suspend因为它可由协程管理。在这里查看更多信息。

suspend因此,如果您在 CoroutineScope 或任何标记的方法中调用API 服务函数时没有对其进行标记suspend,则 Android 应用程序将崩溃并抛出错误Exception in thread "main" java.lang.IllegalArgumentException: Unable to create call adapter for class example.class


Mat*_*wel 14

如果你想使用retrofit2并且你不想总是返回retrofit2.Call<T>,你必须创建自己的CallAdapter.Factory,返回简单类型,如你所愿.简单的代码可能如下所示:

import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Retrofit;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

public class SynchronousCallAdapterFactory extends CallAdapter.Factory {
    public static CallAdapter.Factory create() {
        return new SynchronousCallAdapterFactory();
    }

    @Override
    public CallAdapter<Object, Object> get(final Type returnType, Annotation[] annotations, Retrofit retrofit) {
        // if returnType is retrofit2.Call, do nothing
        if (returnType.toString().contains("retrofit2.Call")) {
            return null;
        }

        return new CallAdapter<Object, Object>() {
            @Override
            public Type responseType() {
                return returnType;
            }

            @Override
            public Object adapt(Call<Object> call) {
                try {
                    return call.execute().body();
                } catch (Exception e) {
                    throw new RuntimeException(e); // do something better
                }
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

然后简单注册SynchronousCallAdapterFactory在Retrofit应该解决你的问题.

Retrofit rest = new Retrofit.Builder()
        .baseUrl(endpoint)
        .addConverterFactory(SimpleXmlConverterFactory.create())
        .addCallAdapterFactory(SynchronousCallAdapterFactory.create())
        .build();
Run Code Online (Sandbox Code Playgroud)

之后,您可以返回简单类型retrofit2.Call.

public interface SimpleService {
    @GET("/simple/{id}")
    Simple getSimple(@Path("id") String id);
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你张贴这个.我已经创建了一个库来处理`Simple getSimple()`和`Response <Simple> getSimple()`requests:https://github.com/jaredsburrows/retrofit2-synchronous-adapter. (3认同)

rah*_*lrv 13

为改造2添加以下依赖项

 compile 'com.squareup.retrofit2:retrofit:2.1.0'
Run Code Online (Sandbox Code Playgroud)

对于GSON

 compile 'com.squareup.retrofit2:converter-gson:2.1.0'
Run Code Online (Sandbox Code Playgroud)

对于可观察的

compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
Run Code Online (Sandbox Code Playgroud)

在您的XML情况下,您必须包含以下依赖项

 compile 'com.squareup.retrofit2:converter-simplexml:2.1.0'
Run Code Online (Sandbox Code Playgroud)

更新服务电话,如下所示

final Retrofit rest = new Retrofit.Builder()
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .addConverterFactory(SimpleXmlConverterFactory.create())
    .baseUrl(endpoint)
    .build();
SimpleService service = rest.create(SimpleService.class);
Run Code Online (Sandbox Code Playgroud)


小智 8

IllegalArgumentException:无法为类 java.lang.Object 创建调用适配器

简短回答:我已经通过以下更改解决了它

ext.retrofit2Version = '2.4.0' -> '2.6.0'
implementation"com.squareup.retrofit2:retrofit:$retrofit2Version"
implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofit2Version"
implementation "com.squareup.retrofit2:converter-gson:$retrofit2Version"
Run Code Online (Sandbox Code Playgroud)

祝你好运