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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32269064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:15:12  来源:igfitidea点击:

Unable to create call adapter for class example.Simple

javarestretrofitsimple-framework

提问by rmuller

I am using retrofit 2.0.0-beta1 with SimpleXml. I want the retrieve a Simple (XML) resource from a REST service. Marshalling/Unmarshalling the Simple object with SimpleXML works fine.

我正在使用带有 SimpleXml 的改造 2.0.0-beta1。我想要从 REST 服务中检索一个简单 (XML) 资源。使用 SimpleXML 编组/解组 Simple 对象工作正常。

When using this code (converted form pre 2.0.0 code):

使用此代码时(转换为 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"));

Service:

服务:

public interface SimpleService {

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

}

I get this exception:

我得到这个例外:

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.invoke(Retrofit.java:127)
    at com.sun.proxy.$Proxy0.getSimple(Unknown Source)

What am i missing? I know that wrapping the return type by a Callworks. But I want the service to return business objects as type (and working in sync mode).

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

UPDATE

更新

After added the extra dependancies and .addCallAdapterFactory(RxJavaCallAdapterFactory.create())as suggested by different answers, I still get this error:

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

Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried:
 * retrofit.RxJavaCallAdapterFactory
 * retrofit.DefaultCallAdapter

采纳答案by Hosam Aly

Short answer: return Call<Simple>in your service interface.

简短回答:Call<Simple>在您的服务接口中返回。

It looks like Retrofit 2.0 is trying to find a way of creating the proxy object for your service interface. It expects you to write this:

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

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

However, it still wants to play nice and be flexible when you don't want to return a Call. To support this, it has the concept of a CallAdapter, which is supposed to know how to adapt a Call<Simple>into a Simple.

但是,当您不想返回Call. 为了支持这一点,它有 a 的概念CallAdapter,它应该知道如何将 a 改编Call<Simple>为 a Simple

The use of RxJavaCallAdapterFactoryis only useful if you are trying to return rx.Observable<Simple>.

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

The simplest solution is to return a Callas Retrofit expects. You could also write a CallAdapter.Factoryif you really need it.

最简单的解决方案是Call按照 Retrofit 的预期返回 a 。CallAdapter.Factory如果你真的需要它,你也可以写一个。

回答by Himanshu Virmani

With the new Retrofit(2.+) you need to add addCallAdapterFactory which can be a normal one or a RxJavaCallAdapterFactory(for Observables). I think you can add more than both too. It automatically checks which one to use. See a working example below. You can also check this linkfor more details.

使用新的 Retrofit(2.+),您需要添加 addCallAdapterFactory,它可以是普通的,也可以是 RxJavaCallAdapterFactory(用于 Observables)。我认为你也可以添加更多。它会自动检查使用哪个。请参阅下面的工作示例。您也可以查看此链接了解更多详情。

 Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiConfig.BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build()

回答by rahulrv

Add the following dependencies for retrofit 2

为改造2添加以下依赖项

 compile 'com.squareup.retrofit2:retrofit:2.1.0'

for GSON

用于 GSON

 compile 'com.squareup.retrofit2:converter-gson:2.1.0'

for observables

对于可观察的

compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

In your case for XML , you would have to include the following dependencies

对于 XML ,您必须包含以下依赖项

 compile 'com.squareup.retrofit2:converter-simplexml:2.1.0'

Update the service call as below

更新服务调用如下

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

回答by Rensodarwin

The way I fixed this issue was adding this to the application gradle file, if the configuration is not set there will be conflicts, maybe this will be fixed in the stable release of the library:

我解决这个问题的方法是将它添加到应用程序 gradle 文件中,如果没有设置配置会有冲突,也许这将在库的稳定版本中修复:

configurations {
    compile.exclude group: 'stax'
    compile.exclude group: 'xpp3'
}

dependencies {
    compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
    compile 'com.squareup.retrofit:converter-simplexml:2.0.0-beta1'
}

and create your adapter this way:

并以这种方式创建您的适配器:

  Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(endPoint)
            .addConverterFactory(SimpleXmlConverterFactory.create())
            .build();

Hope it helps!

希望能帮助到你!

回答by shichaohui

add dependencies:

添加依赖项:

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'

create your adapter this way:

以这种方式创建您的适配器:

Retrofit rest = new Retrofit.Builder()
    .baseUrl(endpoint)
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .addConverterFactory(SimpleXmlConverterFactory.create())
    .build();

addCallAdapterFactory ()and addConverterFactory ()both need to be called.

addCallAdapterFactory ()并且addConverterFactory ()两者都需要被调用。

Service:

服务:

public interface SimpleService {

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

}

Modify Simpleto Call<Simple>.

修改SimpleCall<Simple>.

回答by Sithu

You can implement a Callback, get the Simple from onResponse function.

您可以实现回调,从 onResponse 函数中获取 Simple。

public class MainActivity extends Activity implements Callback<Simple> {

    protected void onCreate(Bundle savedInstanceState) {
        final Retrofit rest = new Retrofit.Builder()
                    .addConverterFactory(SimpleXmlConverterFactory.create())
                    .baseUrl(endpoint)
                    .build();
        SimpleService service = rest.create(SimpleService.class);
        Call<Simple> call = service.getSimple("572642");
        //asynchronous call
        call.enqueue(this);

        return true;
    }

    @Override
    public void onResponse(Response<Simple> response, Retrofit retrofit) {
       // response.body() has the return object(s)
    }

    @Override
    public void onFailure(Throwable t) {
        // do something
    }

}

回答by Mateusz Korwel

If you want use retrofit2and you don't want always return retrofit2.Call<T>, you have to create your own CallAdapter.Factorywhich return simple type as you expected. The simple code can look like this:

如果您想使用retrofit2并且不想总是 return 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
                }
            }
        };
    }
}

Then simple register the SynchronousCallAdapterFactoryin Retrofit should solved your problem.

然后简单的注册SynchronousCallAdapterFactory在改造应该解决你的问题。

Retrofit rest = new Retrofit.Builder()
        .baseUrl(endpoint)
        .addConverterFactory(SimpleXmlConverterFactory.create())
        .addCallAdapterFactory(SynchronousCallAdapterFactory.create())
        .build();

After that you can return simple type without retrofit2.Call.

之后,您可以返回不带retrofit2.Call.

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

回答by Hüseyin Bülbül

in my case using this

在我的情况下使用这个

compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

with this

有了这个

new Retrofit.Builder().addCallAdapterFactory(RxJava2CallAdapterFactory.create())...

solved the problem when nothing else worked

当没有其他工作时解决了问题

回答by Nick Cardoso

Just to make the Call examples clearer for people who are migrating, not using Rx, or who want synchronous calls - Call essentially replaces (wraps) Response, meaning:

只是为了让正在迁移、不使用 Rx 或想要同步调用的人更清楚 Call 示例 - Call 本质上替换(包装)响应,意思是:

Response<MyObject> createRecord(...);

becomes

变成

Call<MyObject> createRecord(...);

and not

并不是

Call<Response<MyObject>> createRecord(...);

(which will still require an adapter)

(这仍然需要一个适配器)



The Call will then allow you to still use isSuccessfulas it actually returns a Response. So you can do something like:

然后调用将允许您仍然使用isSuccessful它,因为它实际上返回一个响应。因此,您可以执行以下操作:

myApi.createRecord(...).execute().isSuccessful()

Or access your Type (MyObject) like:

或访问您的类型(MyObject),如:

MyObject myObj = myApi.createRecord(...).execute().body();

回答by Syed Waqas

public interface SimpleService {

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

}

Communication with the network is done with the separate thread so you should change your Simple with that.

与网络的通信是通过单独的线程完成的,因此您应该使用它来更改 Simple。

public interface SimpleService {

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

}