无法为类示例创建调用适配器

我正在使用 SimpleXml 对2.0.0-beta1进行改造,我希望从 REST 服务检索 Simple (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"));

服务范围:

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包装返回类型是可行的。但是我希望服务以类型返回业务对象(并在同步模式下工作)。

更新

在按照不同的答案添加了额外的依赖关系和 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())之后,我仍然得到这个错误:

Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried:
* retrofit.RxJavaCallAdapterFactory
* retrofit.DefaultCallAdapter$1
140958 次浏览

新的翻新工程(2。+)您需要添加 addCallAdapterFactory,它可以是普通的 addCallAdapterFactory,也可以是 RxJavaCallAdapterFactory (针对可观察对象)。我觉得你也可以两者兼顾。它会自动检查使用哪一个。请参阅下面的工作示例。您也可以检查 这个链接了解更多细节。

 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);

我修复这个问题的方法是将它添加到应用程序的 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'
}

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

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

希望能有帮助!

添加依赖项:

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'

这样创建适配器:

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>

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

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

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

然而,当你不想返回一个 Call的时候,它仍然希望表现的很好并且很灵活。为了支持这一点,它有一个 CallAdapter的概念,这个概念应该知道如何将一个 Call<Simple>改编成一个 Simple

只有在试图返回 rx.Observable<Simple>时,使用 RxJavaCallAdapterFactory才有用。

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

您可以实现 Callback,获取 Simple from 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
}


}

如果你想使用 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
}
}
};
}
}

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

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

在此之后,您可以返回没有 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())...

在其他方法都不起作用的时候解决了问题

只是为了让调用示例对于正在迁移的人、不使用 Rx 的人或者想要同步调用的人更加清晰—— Call 实际上是替换(包装) Response,意思是:

Response<MyObject> createRecord(...);

变成了

Call<MyObject> createRecord(...);

而不是

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

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


然后,Call 将允许您仍然使用 isSuccessful,因为它实际上返回一个 Response。所以你可以这样做:

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

或者访问你的类型(MyObject) ,比如:

MyObject myObj = myApi.createRecord(...).execute().body();
public interface SimpleService {


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


}

与网络的通信是用单独的线程完成的,所以您应该改变您的简单与该。

public interface SimpleService {


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


}

对我来说

com.squareup.retrofit2:adapter-rxjava:2.5.0 //notice rxjava

而不是

com.squareup.retrofit2:adapter-rxjava2:2.5.0 //notice rxjava2

使用 io.reactivex.rxjava2时应使用 com.squareup.retrofit2:adapter-rxjava2:2.5.0

如果您没有正确地使用 RxJava,那么添加 RxJava 只是为了进行改造是没有意义的。2.5.0支持内置的 CompletableFuture,您可以在不添加任何其他库或适配器的情况下使用它。

build.gradle.kts

implementation("com.squareup.retrofit2:retrofit:2.5.0")
implementation("com.squareup.retrofit2:retrofit-converters:2.5.0")

Api.kt

interface Api {
@GET("/resource")
fun listCompanies(): CompletableFuture<ResourceDto>
}

用法:

Retrofit.Builder()
.addConverterFactory(SimpleXmlConverterFactory.create())
.baseUrl("https://api.example.com")
.build()
.create(Api::class.java)

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"

祝你好运

科特林协同动作的情况下,当我从 CoroutineScope(Dispatchers.IO).launch{}调用这个函数时忘记将 api 服务函数标记为 suspend时,就会发生这种情况:

用法:

    val apiService = RetrofitFactory.makeRetrofitService()


CoroutineScope(Dispatchers.IO).launch {


val response = apiService.myGetRequest()


// process response...


}

ApiService.kt

interface ApiService {


@GET("/my-get-request")
suspend fun myGetRequest(): Response<String>
}

我已经找到了一个解决方案,在我的情况下是,我使用从 JAVA 的 ApiInterface.java连接到来自 KOTLIN 的 MyViewModel.kt

  1. 这是 ApiInterface.java

    @ GET (Constant.Connection) 调用 < com.example.kt.model. ConnectionResponse > ConnectionKt () ;

  2. 您需要创建一个名为 ApiTemporary.kt的新 Kotlin 类

    临时类( Private val apiInterface: ApiInterface = GetRevifitInstance () . create (ApiInterface: : class.java) ) {

    挂起 fun getConnectionKt () : 响应{ 返回 apiInterface. ConnectionKt () . awaitResponse () } }

  3. 最后,在 MyViewModel.kt,你可以这样做

Val data = withContext (ioDispatcher){ Val result = api颞 ary.getConnectionKt () 如果(结果是成功的){ Resource.Success (result. body ()) { Resource.Error (“服务器错误,请重试”) } } 值 = 数据

因此,ApiTemporary将有助于将它们从爪哇转换为 Kotlin,这是 Coroutines 的用法

我解决了通过更新翻新版本的2.9

如果您的 API 接口返回 Response 对象,那么您可能忘记在 API 接口中添加挂起函数。

API 接口

interface WeatherAPI {
@GET("/data/2.5/weather")
suspend fun getWeatherInfo(
@Query("q") query: String
): Response<WeatherResponse>
}

仓库

class WeatherRepositoryImpl @Inject constructor(
private val weatherAPI: WeatherAPI
) : WeatherRepository {
override suspend fun getWeatherInfo(query: String): Resource<WeatherResponse> {
try {
val response = weatherAPI.getWeatherInfo(query)
if (response.isSuccessful) {
response.body()?.let {
return Resource.success(it)
} ?: return Resource.error("Unknown error occurred", null)
} else {
return Resource.error("Unknown error occured", null)
}
} catch (e: Exception) {
return Resource.error("Please check your internet connection", null)
}
}


}

在这种情况下:

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>
}

suspend函数中使用的所有方法都必须标记为 suspend,因为它是可由 Corountine 管理的。查看更多信息 给你

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

我使用的协程与 CoroutineCallAdapterFactory,但意外地忘记使函数 suspend。希望它有所帮助的人!