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
Unable to create call adapter for class example.Simple
提问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 Call
works. 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 RxJavaCallAdapterFactory
is only useful if you are trying to return rx.Observable<Simple>
.
的使用RxJavaCallAdapterFactory
仅在您尝试返回时有用rx.Observable<Simple>
。
The simplest solution is to return a Call
as Retrofit expects. You could also write a CallAdapter.Factory
if 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 Simple
to Call<Simple>
.
修改Simple
为Call<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 retrofit2
and you don't want always return retrofit2.Call<T>
, you have to create your own CallAdapter.Factory
which 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 SynchronousCallAdapterFactory
in 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 isSuccessful
as 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);
}