Android 从挂起函数异常返回对象
安卓项目: 片段:Android 从挂起函数异常返回对象,android,deferred,kotlin-coroutines,Android,Deferred,Kotlin Coroutines,安卓项目: 片段: import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okhttp3.MediaType import okhttp3.ResponseBody import retrofit2.Response class DefaultTransportService { companion obje
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.MediaType
import okhttp3.ResponseBody
import retrofit2.Response
class DefaultTransportService {
companion object {
private val SERVICE_UNAVAILABLE = "{\n" +
" \"code\": -1,\n" + // 503
" \"message\": \"Service unavailable\"\n" +
"}"
private val TAG = DefaultTransportService::class.java.name
suspend fun executeOperation(operation: Deferred<Response<*>>): Any = withContext(Dispatchers.IO) {
try {
operation.await()
} catch (e: Throwable) {
val resultResponse = Response.error<Any>(-1, ResponseBody.create(
MediaType.parse("application/json"),
SERVICE_UNAVAILABLE
))
return resultResponse
}
}
}
}
我发现编译错误:
'return' is not allowed here
但是当
操作时,我需要更改响应。wait()
抛出任何异常。IMHO在您的情况下,我将使您的挂起函数返回一个密封类,类似于:
suspend fun doSomething():响应=
SuspendCancelableCoroutine{cont->
试一试{
//在这里工作
cont.resume(Response.Success())
}捕获(e:例外){
val error=“服务不可用”
继续恢复(响应错误(错误))
Log.e(标记,e.message)
}
}
密封类响应{
班级成功:回应()
类错误(val消息:字符串?):响应()
}
1-创建密封类。
返回一个密封的类,类似于我已经提到的,但它接受T
键入以返回结果
sealed class Result<out T> {
data class Success<out T>(val result: T): Result<T>()
data class Failure<out T>(val exception: Exception) : Result<T>()
}
密封类结果{
数据类成功(val结果:T):结果()
数据类失败(val异常:异常):结果()
}
2-使用
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val result = fetch()
when (result) {
is Result.Success -> {
val obj = result.result
}
is Result.Failure -> {
Log.e(TAG, result.exception)
}
}
}
fun fetch(): Result<Object> {
try {
return Result.Success(obj)
} catch(e: Exception) {
return Result.Failure(e)
}
}
override-fun-onCreate(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val result=fetch()
何时(结果){
这就是结果。成功->{
val obj=result.result
}
是结果。失败->{
Log.e(标记、结果、异常)
}
}
}
fun fetch():结果{
试试{
返回结果。成功(obj)
}捕获(e:例外){
返回结果。失败(e)
}
}
密封类更显式,但从技术上讲,您不需要密封类,因为您可以使用resumeWithException
传播异常
例如:
suspend fun update() : Any = suspendCancellableCoroutine{ cont ->
launch {
try {
// Some suspend functions that could throw exceptions
val response = getData()
parseData(response)
cont.resume(Unit)
}catch (e : Exception){
cont.resumeWithException(e)
}
}
}
用法
只需删除return
,您不需要在lambda中使用它
suspend fun update() : Any = suspendCancellableCoroutine{ cont ->
launch {
try {
// Some suspend functions that could throw exceptions
val response = getData()
parseData(response)
cont.resume(Unit)
}catch (e : Exception){
cont.resumeWithException(e)
}
}
}
try {
network.update()
}catch (e: Exception) {
// Handle your exceptions as usual
when (e){
is ParseException -> emit(Status.PARSING_ERROR)
is NetworkException -> emit(Status.NETWORK_UNAVAILABLE
// etc...
}