我正在开发一个 Android 应用程序。
我正在使用 Retrofit2 和 Coroutine 从我的 Rest API 中获取一些数据。
当我的 Rest API 中抛出异常时,它会返回异常代码和异常消息,其中 HTTP 状态 = 4xx 或 5xx,如下面的屏幕截图所示
如果响应是异常,则根据以下代码将 exceptionCode 和 exceptionMessage 映射到我的 Android 应用程序中的响应。
val exceptionBody = Gson().fromJson(response.errorBody()?.string(), ExceptionResponse::class.java)
这是ExceptionResponse
类(class)data class ExceptionResponse(
val exceptionCode: String,
val exceptionMessage: String
)
这是一个问题。当我做 response.errorBody()?.string()
,Android Studio 给我一个警告说“不适当的阻塞方法调用”这是我的
repository
调用网络调用override fun fetchData() {
CoroutineScope(Dispatchers.IO).launch {
val fetchedData = myRemoteDataSource.fetchData()
}
}
这里是 MyRemoteDataSource
类(class)class MyRemoteDataSourceImpl(
private val myAPIService: MyAPIService
): BaseRemoteDataSource(), MyRemoteDataSource {
override suspend fun fetchData(): Resource<List<Data>> {
return getResult {
myAPIService.fetchData()
}
}
}
这是我的BaseRemoteDataSource
具有 getResult()
的类在哪里 errorBody.string
叫做正如您在上面的屏幕截图中看到的那样,唯一没有给我警告的协程是最后一个
GlobalScope.launch(Dispatchers.IO) {
Gson().fromJson(response.errorBody()?.string(), ExceptionResponse::class.java)
}
所以我对这个警告和 coroutineScope 有几个问题GlobalScope.launch(Dispatchers.IO) {
Gson().fromJson(response.errorBody()?.string(), ExceptionResponse::class.java)
}
CoroutineScope
或 GlobalScope
那么我将返回 null 除非我使用 scope.join
.那么我不应该使用使用父/调用者的协程范围进行结构化并发的 coroutineScope() 吗? string()
的源代码 public final String string() throws IOException {
try (BufferedSource source = source()) {
Charset charset = Util.bomAwareCharset(source, charset());
return source.readString(charset);
}
}
很抱歉一次转储问题,但它们都是相关的。感谢你们!!!
最佳答案
在 IO
中调用阻塞执行是正常的。上下文,因为它旨在执行此类任务。所以我认为最好的方法是在 ResponseBody
上写一个扩展函数。在 IO
中进行操作上下文适当。但是,在这个函数上,也出现了警告,但我们知道我们处理得很好,我们可以抑制它。
@Suppress("BlockingMethodInNonBlockingContext")
suspend fun ResponseBody.stringSuspending() =
withContext(Dispatchers.IO) { string() }
所以我们确信ResponseBody.string()
将在 IO
中执行上下文,无论它可能被另一个上下文包装:Gson().fromJson(response.errorBody()?.stringSuspending(), ExceptionResponse::class.java)
关于android - 改造 response.errorBody.string() 给了我暂停函数中不适当的阻塞方法调用的警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64190661/