延迟改造请求响应问题
Deferred retrofit request response problem
我想对我的 Retrofit 请求执行异步等待。
@GET("{companyId}/{filename}")
@Streaming
suspend fun getFilePart(
@Path(value = "companyId") companyId: Int,
@Path(value = "filename") filename: String,
@QueryMap queryMap: Map<String, String>
): Deferred<ResponseBody>
当我从 CoroutineScope 调用它时,我有
val deferredList = pendingFiles.map {
async(Dispatchers.IO) {
try {
// runs in parallel in background thread
// Consider i have the data parameters....
apiManager.mApiService(base).getFilePart(it.companyId, fileName, urlQueryMap)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
所以请求 returns 200 这意味着它是成功的,我看到了带有文件部分数据的日志记录。但是我得到以下异常
W/System.err: java.lang.RuntimeException: Unable to invoke no-args constructor for com.google.firebase.inject.Deferred<okhttp3.ResponseBody>. Registering an InstanceCreator with Gson for this type may fix this problem.
W/System.err: at com.google.gson.internal.ConstructorConstructor.construct(ConstructorConstructor.java:228)
W/System.err: at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212)
W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:40)
W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
W/System.err: at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
W/System.err: at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:153)
W/System.err: at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:520)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:920)
W/System.err: Caused by: java.lang.UnsupportedOperationException: Interface can't be instantiated! Interface name: com.google.firebase.inject.Deferred
W/System.err: at com.google.gson.internal.UnsafeAllocator.assertInstantiable(UnsafeAllocator.java:117)
W/System.err: at com.google.gson.internal.UnsafeAllocator.newInstance(UnsafeAllocator.java:49)
W/System.err: at com.google.gson.internal.ConstructorConstructor.construct(ConstructorConstructor.java:225)
W/System.err: ... 9 more
如果您的函数是 suspend
,则不应 return Deferred
。只需这样声明即可:
@GET("{companyId}/{filename}")
@Streaming
suspend fun getFilePart(
@Path(value = "companyId") companyId: Int,
@Path(value = "filename") filename: String,
@QueryMap queryMap: Map<String, String>
): ResponseBody // no Deferred here
带有 suspend
关键字的函数像常规函数一样使用(这就是协同程序的优点),因此它们 return 是常规类型。当你像使用 async
一样使用协程构建器时,你实际上开始了异步代码 - 这是 returns Deferred<T>
并且没有挂起的代码。
我想对我的 Retrofit 请求执行异步等待。
@GET("{companyId}/{filename}")
@Streaming
suspend fun getFilePart(
@Path(value = "companyId") companyId: Int,
@Path(value = "filename") filename: String,
@QueryMap queryMap: Map<String, String>
): Deferred<ResponseBody>
当我从 CoroutineScope 调用它时,我有
val deferredList = pendingFiles.map {
async(Dispatchers.IO) {
try {
// runs in parallel in background thread
// Consider i have the data parameters....
apiManager.mApiService(base).getFilePart(it.companyId, fileName, urlQueryMap)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
所以请求 returns 200 这意味着它是成功的,我看到了带有文件部分数据的日志记录。但是我得到以下异常
W/System.err: java.lang.RuntimeException: Unable to invoke no-args constructor for com.google.firebase.inject.Deferred<okhttp3.ResponseBody>. Registering an InstanceCreator with Gson for this type may fix this problem.
W/System.err: at com.google.gson.internal.ConstructorConstructor.construct(ConstructorConstructor.java:228)
W/System.err: at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212)
W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:40)
W/System.err: at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
W/System.err: at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
W/System.err: at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:153)
W/System.err: at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:520)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:920)
W/System.err: Caused by: java.lang.UnsupportedOperationException: Interface can't be instantiated! Interface name: com.google.firebase.inject.Deferred
W/System.err: at com.google.gson.internal.UnsafeAllocator.assertInstantiable(UnsafeAllocator.java:117)
W/System.err: at com.google.gson.internal.UnsafeAllocator.newInstance(UnsafeAllocator.java:49)
W/System.err: at com.google.gson.internal.ConstructorConstructor.construct(ConstructorConstructor.java:225)
W/System.err: ... 9 more
如果您的函数是 suspend
,则不应 return Deferred
。只需这样声明即可:
@GET("{companyId}/{filename}")
@Streaming
suspend fun getFilePart(
@Path(value = "companyId") companyId: Int,
@Path(value = "filename") filename: String,
@QueryMap queryMap: Map<String, String>
): ResponseBody // no Deferred here
带有 suspend
关键字的函数像常规函数一样使用(这就是协同程序的优点),因此它们 return 是常规类型。当你像使用 async
一样使用协程构建器时,你实际上开始了异步代码 - 这是 returns Deferred<T>
并且没有挂起的代码。