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 w
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.
Service:
public interface SimpleService {
@GET("/simple/{id}")
Call<Simple> getSimple(@Path("id") String id);
}
Modify Simple
to Call<Simple>
.
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:
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!
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:
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.
Retrofit rest = new Retrofit.Builder()
.baseUrl(endpoint)
.addConverterFactory(SimpleXmlConverterFactory.create())
.addCallAdapterFactory(SynchronousCallAdapterFactory.create())
.build();
After that you can return simple type without retrofit2.Call
.
public interface SimpleService {
@GET("/simple/{id}")
Simple getSimple(@Path("id") String id);
}
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
IllegalArgumentException: Unable to create call adapter for class java.lang.Object
Short answer: I have solved it by the following changes
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"
Good luck
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 link for more details.
Retrofit retrofit = new Retrofit.Builder().baseUrl(ApiConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()