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...
}