如何创建呼叫适配器以在改造中暂停功能?
2022-09-01 05:12:25
我需要创建一个可以处理此类网络呼叫的改造呼叫适配器:
@GET("user")
suspend fun getUser(): MyResponseWrapper<User>
我希望它能在不使用的情况下与 Kotlin Coroutines 配合使用。我已经有一个成功的实现 using ,它可以处理如下方法:Deferred
Deferred
@GET("user")
fun getUser(): Deferred<MyResponseWrapper<User>>
但是我想要能够使该函数成为挂起函数并删除包装器。Deferred
对于挂起功能,改造就像在返回类型周围有一个包装器一样,因此被视为Call
suspend fun getUser(): User
fun getUser(): Call<User>
我的实现
我试图创建一个调用适配器来处理这个问题。以下是我到目前为止的实现:
厂
class MyWrapperAdapterFactory : CallAdapter.Factory() {
override fun get(returnType: Type, annotations: Array<Annotation>, retrofit: Retrofit): CallAdapter<*, *>? {
val rawType = getRawType(returnType)
if (rawType == Call::class.java) {
returnType as? ParameterizedType
?: throw IllegalStateException("$returnType must be parameterized")
val containerType = getParameterUpperBound(0, returnType)
if (getRawType(containerType) != MyWrapper::class.java) {
return null
}
containerType as? ParameterizedType
?: throw IllegalStateException("MyWrapper must be parameterized")
val successBodyType = getParameterUpperBound(0, containerType)
val errorBodyType = getParameterUpperBound(1, containerType)
val errorBodyConverter = retrofit.nextResponseBodyConverter<Any>(
null,
errorBodyType,
annotations
)
return MyWrapperAdapter<Any, Any>(successBodyType, errorBodyConverter)
}
return null
}
适配器
class MyWrapperAdapter<T : Any>(
private val successBodyType: Type
) : CallAdapter<T, MyWrapper<T>> {
override fun adapt(call: Call<T>): MyWrapper<T> {
return try {
call.execute().toMyWrapper<T>()
} catch (e: IOException) {
e.toNetworkErrorWrapper()
}
}
override fun responseType(): Type = successBodyType
}
runBlocking {
val user: MyWrapper<User> = service.getUser()
}
使用此实现,一切都按预期工作,但在将网络调用的结果传递到变量之前,我收到以下错误:user
java.lang.ClassCastException: com.myproject.MyWrapper cannot be cast to retrofit2.Call
at retrofit2.HttpServiceMethod$SuspendForBody.adapt(HttpServiceMethod.java:185)
at retrofit2.HttpServiceMethod.invoke(HttpServiceMethod.java:132)
at retrofit2.Retrofit$1.invoke(Retrofit.java:149)
at com.sun.proxy.$Proxy6.getText(Unknown Source)
...
从Retrofit的来源,这是代码段:HttpServiceMethod.java:185
@Override protected Object adapt(Call<ResponseT> call, Object[] args) {
call = callAdapter.adapt(call); // ERROR OCCURS HERE
//noinspection unchecked Checked by reflection inside RequestFactory.
Continuation<ResponseT> continuation = (Continuation<ResponseT>) args[args.length - 1];
return isNullable
? KotlinExtensions.awaitNullable(call, continuation)
: KotlinExtensions.await(call, continuation);
}
我不确定如何处理此错误。有没有办法解决?