无法为 class example.Simple 创建呼叫适配器
Unable to create call adapter for class example.Simple
我正在使用带有 SimpleXml 的改造 2.0.0-beta1。我想从 REST 服务中检索一个简单 (XML) 资源。
Marshalling/Unmarshalling 带有 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.invoke(Retrofit.java:127)
at com.sun.proxy.$Proxy0.getSimple(Unknown Source)
我错过了什么?我知道用 Call
包装 return 类型是可行的。但我希望服务以 return 业务对象为类型(并在同步模式下工作)。
更新
按照不同答案的建议添加了额外的依赖项和 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
后,我仍然收到此错误:
Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried:
* retrofit.RxJavaCallAdapterFactory
* retrofit.DefaultCallAdapter
对于新的 Retrofit(2.+),您需要添加 addCallAdapterFactory,它可以是普通的或 RxJavaCallAdapterFactory(用于 Observables)。我认为你也可以添加更多。它会自动检查使用哪一个。请参阅下面的工作示例。您还可以查看 this link 了解更多详情。
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>
.
简答:return Call<Simple>
在您的服务界面中。
看起来 Retrofit 2.0 正在尝试找到一种为您的服务接口创建代理对象的方法。它希望你这样写:
public interface SimpleService {
@GET("/simple/{id}")
Call<Simple> getSimple(@Path("id") String id);
}
然而,当你不想 return Call
时,它仍然想表现得很好并且灵活。为了支持这一点,它有一个 CallAdapter
的概念,它应该知道如何将 Call<Simple>
改编成 Simple
。
RxJavaCallAdapterFactory
的使用仅在您尝试 return rx.Observable<Simple>
.
时有用
最简单的解决方案是 return a Call
正如 Retrofit 所期望的那样。如果你真的需要它,你也可以写一个CallAdapter.Factory
。
你可以实现一个Callback,从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
}
}
如果你想使用 retrofit2
而你不想总是 return retrofit2.Call<T>
,你必须创建自己的 CallAdapter.Factory
,return 简单按预期输入。简单的代码可以是这样的:
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();
之后你可以 return 没有 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 示例 - Call 本质上取代(包装)Response,意思是:
Response<MyObject> createRecord(...);
变成
Call<MyObject> createRecord(...);
而不是
Call<Response<MyObject>> createRecord(...);
(仍然需要适配器)
呼叫将允许您仍然使用 isSuccessful
因为它实际上是 returns 一个响应。所以你可以这样做:
myApi.createRecord(...).execute().isSuccessful()
或像这样访问您的类型 (MyObject):
MyObject myObj = myApi.createRecord(...).execute().body();
public interface SimpleService {
@GET("/simple/{id}")
Simple getSimple(@Path("id") String id);
}
与网络的通信是通过单独的线程完成的,因此您应该用它来更改 Simple。
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:无法为 class 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"
祝你好运
在 Kotlin 和 coroutines 的情况下,当我忘记将 api 服务函数标记为 [=12 时,就会发生这种情况=] 当我从 CoroutineScope(Dispatchers.IO).launch{}
:
调用这个函数时
用法:
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
。
这是ApiInterface.java
@GET(Constant.CONNECTION)
调用ConnectionKt();
您需要创建一个新的 Kotlin class,命名为 ApiTemporary.kt
class ApiTemporary(
私有 val apiInterface: ApiInterface =
RetrofitClient.getRetrofitInstance().create(ApiInterface::class.java)
) {
暂停乐趣 getConnectionKt(): 响应 {
return apiInterface.ConnectionKt().awaitResponse()
}
}
最后,在 MyViewModel.kt
,你可以这样做
val data = withContext(ioDispatcher) {
val 结果 = apiTemporary.getConnectionKt()
如果(result.isSuccessful){
Resource.Success(result.body())
} 别的 {
Resource.Error("服务器错误,请重试")
}
}
_connection.value = 数据
因此,ApiTemporary
将有助于将它们从 Java 转换为使用协程的 Kotlin
我在 gradle
中通过更新改造版本到 2.9.0 解决了
如果您的 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 管理。查看更多信息 here.
因此,如果在 CoroutineScope 或任何 suspend
标记的方法中调用它时,如果您没有将 API 服务函数标记为 suspend
,android 应用程序会崩溃并抛出Exception in thread "main" java.lang.IllegalArgumentException: Unable to create call adapter for class example.class
错误。
我正在使用带有 SimpleXml 的改造 2.0.0-beta1。我想从 REST 服务中检索一个简单 (XML) 资源。 Marshalling/Unmarshalling 带有 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.invoke(Retrofit.java:127)
at com.sun.proxy.$Proxy0.getSimple(Unknown Source)
我错过了什么?我知道用 Call
包装 return 类型是可行的。但我希望服务以 return 业务对象为类型(并在同步模式下工作)。
更新
按照不同答案的建议添加了额外的依赖项和 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
后,我仍然收到此错误:
Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for class simple.Simple. Tried:
* retrofit.RxJavaCallAdapterFactory
* retrofit.DefaultCallAdapter
对于新的 Retrofit(2.+),您需要添加 addCallAdapterFactory,它可以是普通的或 RxJavaCallAdapterFactory(用于 Observables)。我认为你也可以添加更多。它会自动检查使用哪一个。请参阅下面的工作示例。您还可以查看 this link 了解更多详情。
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>
.
简答:return Call<Simple>
在您的服务界面中。
看起来 Retrofit 2.0 正在尝试找到一种为您的服务接口创建代理对象的方法。它希望你这样写:
public interface SimpleService {
@GET("/simple/{id}")
Call<Simple> getSimple(@Path("id") String id);
}
然而,当你不想 return Call
时,它仍然想表现得很好并且灵活。为了支持这一点,它有一个 CallAdapter
的概念,它应该知道如何将 Call<Simple>
改编成 Simple
。
RxJavaCallAdapterFactory
的使用仅在您尝试 return rx.Observable<Simple>
.
最简单的解决方案是 return a Call
正如 Retrofit 所期望的那样。如果你真的需要它,你也可以写一个CallAdapter.Factory
。
你可以实现一个Callback,从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
}
}
如果你想使用 retrofit2
而你不想总是 return retrofit2.Call<T>
,你必须创建自己的 CallAdapter.Factory
,return 简单按预期输入。简单的代码可以是这样的:
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();
之后你可以 return 没有 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 示例 - Call 本质上取代(包装)Response,意思是:
Response<MyObject> createRecord(...);
变成
Call<MyObject> createRecord(...);
而不是
Call<Response<MyObject>> createRecord(...);
(仍然需要适配器)
呼叫将允许您仍然使用 isSuccessful
因为它实际上是 returns 一个响应。所以你可以这样做:
myApi.createRecord(...).execute().isSuccessful()
或像这样访问您的类型 (MyObject):
MyObject myObj = myApi.createRecord(...).execute().body();
public interface SimpleService {
@GET("/simple/{id}")
Simple getSimple(@Path("id") String id);
}
与网络的通信是通过单独的线程完成的,因此您应该用它来更改 Simple。
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:无法为 class 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"
祝你好运
在 Kotlin 和 coroutines 的情况下,当我忘记将 api 服务函数标记为 [=12 时,就会发生这种情况=] 当我从 CoroutineScope(Dispatchers.IO).launch{}
:
用法:
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
。
这是
ApiInterface.java
@GET(Constant.CONNECTION) 调用
ConnectionKt(); 您需要创建一个新的 Kotlin class,命名为
ApiTemporary.kt
class ApiTemporary( 私有 val apiInterface: ApiInterface = RetrofitClient.getRetrofitInstance().create(ApiInterface::class.java) ) {
暂停乐趣 getConnectionKt(): 响应 { return apiInterface.ConnectionKt().awaitResponse() } }
最后,在
MyViewModel.kt
,你可以这样做
val data = withContext(ioDispatcher) { val 结果 = apiTemporary.getConnectionKt() 如果(result.isSuccessful){ Resource.Success(result.body()) } 别的 { Resource.Error("服务器错误,请重试") } } _connection.value = 数据
因此,ApiTemporary
将有助于将它们从 Java 转换为使用协程的 Kotlin
我在 gradle
中通过更新改造版本到 2.9.0 解决了如果您的 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 管理。查看更多信息 here.
因此,如果在 CoroutineScope 或任何 suspend
标记的方法中调用它时,如果您没有将 API 服务函数标记为 suspend
,android 应用程序会崩溃并抛出Exception in thread "main" java.lang.IllegalArgumentException: Unable to create call adapter for class example.class
错误。