无法为类example.Simple创build调用适配器
我正在使用SimpleXml进行改进2.0.0-beta1。 我想从REST服务中检索一个简单的(XML)资源。 用SimpleXML对Simple对象进行编组/解组工作正常。
当使用这个代码(转换后的forms前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"));
服务:
public interface SimpleService { @GET("/simple/{id}") Simple getSimple(@Path("id") String id); }
我得到这个例外:
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)
我错过了什么? 我知道,通过Call
包装返回types的作品。 但我希望该服务返回types的业务对象(并在同步模式下工作)。
UPDATE
添加额外的依赖和.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
不同的答案build议后,我仍然得到这个错误:
Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried: * retrofit.RxJavaCallAdapterFactory * retrofit.DefaultCallAdapter$1
简短的回答:返回在您的服务界面中Call<Simple>
。
它看起来像Retrofit 2.0试图find一种为您的服务接口创build代理对象的方法。 它期望你写这个:
public interface SimpleService { @GET("/simple/{id}") Call<Simple> getSimple(@Path("id") String id); }
但是,如果您不想返回Call
,它仍然希望玩得很好,并保持灵活性。 为了支持这一点,它有一个CallAdapter
的概念,它应该知道如何将Call<Simple>
为Simple
。
RxJavaCallAdapterFactory
的使用仅在您尝试返回rx.Observable<Simple>
时才有用。
最简单的解决scheme是返回Call
作为改造期望。 如果你真的需要的话,你也可以写一个CallAdapter.Factory
。
添加依赖关系:
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'
用这种方法创build适配器:
Retrofit rest = new Retrofit.Builder() .baseUrl(endpoint) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(SimpleXmlConverterFactory.create()) .build();
需要调用addCallAdapterFactory ()
和addConverterFactory ()
。
服务:
public interface SimpleService { @GET("/simple/{id}") Call<Simple> getSimple(@Path("id") String id); }
修改Simple
Call<Simple>
。
使用新的Retrofit(2. +),您需要添加addCallAdapterFactory,它可以是普通的或者RxJavaCallAdapterFactory(对于Observable)。 我认为你可以添加更多。 它会自动检查使用哪一个。 看下面的一个工作示例。 您也可以查看此链接了解更多详情。
Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiConfig.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build()
添加以下依赖关系进行改造2
compile 'com.squareup.retrofit2:retrofit:2.1.0'
为GSON
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
为了观察
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
在你的情况下的XML,你将不得不包括以下依赖项
compile 'com.squareup.retrofit2:converter-simplexml:2.1.0'
更新服务电话如下
final Retrofit rest = new Retrofit.Builder() .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(SimpleXmlConverterFactory.create()) .baseUrl(endpoint) .build(); SimpleService service = rest.create(SimpleService.class);
如果你想使用CallAdapter.Factory
,你不想总是返回CallAdapter.Factory
retrofit2.Call<T>
,你必须创build自己的CallAdapter.Factory
,它可以像你期望的那样返回简单的types。 简单的代码可以像这样:
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 } } }; } }
然后在Retrofit中简单的注册SynchronousCallAdapterFactory
应该可以解决你的问题。
Retrofit rest = new Retrofit.Builder() .baseUrl(endpoint) .addConverterFactory(SimpleXmlConverterFactory.create()) .addCallAdapterFactory(SynchronousCallAdapterFactory.create()) .build();
之后,你可以返回简单的types,而不retrofit2.Call
。
public interface SimpleService { @GET("/simple/{id}") Simple getSimple(@Path("id") String id); }
在我的情况下使用这个
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
有了这个
new Retrofit.Builder().addCallAdapterFactory(RxJava2CallAdapterFactory.create())...
解决了没有其他工作的问题
你可以实现一个callback,从onResponse函数获取简单。
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 } }
我解决这个问题的方法是将其添加到应用程序gradle文件中,如果没有设置configuration将会有冲突,也许这将在库的稳定版本中被修复:
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' }
并以这种方式创build适配器:
Retrofit retrofit = new Retrofit.Builder() .baseUrl(endPoint) .addConverterFactory(SimpleXmlConverterFactory.create()) .build();
希望能帮助到你!
最新改造用途(2017年7月):
正确使用库版本。
新版本是
compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex.rxjava2:rxjava:2.1.0' compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
1)确保你有相同的改造和改造RxJava适配器。
2) 使用
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
不
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'