Phi*_*lly 18 android retrofit retrofit2 kotlin-coroutines
我正在使用带有 Kotlin 协程的 Retrofit 2.7.1。
我有一个 Retrofit 服务定义如下:
@PUT("/users/{userId}.json")
suspend fun updateUserProfile(
@Path("userId") userId: String,
@Query("display_name") displayName: String) : Void
Run Code Online (Sandbox Code Playgroud)
此调用返回HTTP 204 No Content响应,这会导致 Retrofit 崩溃:
kotlin.KotlinNullPointerException: Response from com.philsoft.test.api.UserApiService.updateUserProfile was null but response body type was declared as non-null
at retrofit2.KotlinExtensions$await$2$2.onResponse(KotlinExtensions.kt:43)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:129)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Run Code Online (Sandbox Code Playgroud)
如何在改造中使用协程处理 204 响应而不会崩溃?
sav*_*ion 10
您可以使用Response<Unit>来处理 204 个响应,Retrofit但是当您像这样处理时,Retrofit不会为4xx响应或其他异常情况抛出异常。
您可以使用以下代码处理这些情况:
return try {
val result = apiCall.invoke()
return if (result is Response<*>) {
if (result.code() >= 400) {
// create an error from error body and return
} else {
// return success result
}
} else {
// directly return success result
}
} catch (t: Throwable) {
// create an error from throwable and return it!
}
Run Code Online (Sandbox Code Playgroud)
用示例代码解释@Dmitri 的答案:
在您的 APIInterface 中,像这样调用您的 API,
@GET(AppConstants.APIEndPoints.GET_NEWS)
suspend fun getNews(
@Query("limit") limit: String,
): Response<NewsListResponseModel>
Run Code Online (Sandbox Code Playgroud)
其中,响应是 retrofit2.Response
从调用 API 的位置,检查来自函数的状态代码,例如apiResponse.code().
val apiResponse = apiEndPointsInterface.getNews(limit)
if (apiResponse.code() == HttpURLConnection.HTTP_OK) {
//response success
ResultOf.Success(apiResponse.body()!!))
} else {
//something went wrong
ResultOf.Failure("No Data Found.", null))
}
Run Code Online (Sandbox Code Playgroud)
204使用自定义拦截器将's更改为200's 对我有用
class Code204Interceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
return if (response.code == 204) {
response.newBuilder().code(200).build()
} else {
response
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7238 次 |
| 最近记录: |