gpt4 book ai didi

android - Kotlin 协程处理错误和实现

转载 作者:太空宇宙 更新时间:2023-11-03 11:54:17 26 4
gpt4 key购买 nike

第一次使用协程。需要帮助。

这是我的流程:

Presenter 想要登录所以调用 Repository Interface。 Repository 实现 RepositoryInterface。所以 Repository 调用 APIInterface。 APIInterface由APIInterfaceImpl实现。APIInterfaceImpl 最后调用MyRetrofitInterface。

这是流程图:

Presenter -> Repository -> APIInterfaceImpl -> MyRetrofitInterface

一旦我收到登录响应:

APIInterfaceImpl -> Repository -> 将数据存储在缓存中 -> 将 http 状态代码提供给 Presenter

这是我的代码:

存储库接口(interface).kt

fun onUserLogin(loginRequest: LoginRequest): LoginResponse

存储库.kt

class Repository : RepositoryInterface {
private var apiInterface: APIInterface? = null

override fun onUserLogin(loginRequest: LoginRequest): LoginResponse {
return apiInterface?.makeLoginCall(loginRequest)
}
}

API接口(interface).kt

suspend fun makeLoginCall(loginRequest): LoginResponse?

APIInterfaceImpl.kt

override suspend fun makeLoginCall(loginRequest: LoginRequest): LoginResponse? {
if (isInternetPresent(context)) {
try {
val response = MyRetrofitInterface?.loginRequest(loginRequest)?.await()
return response
} catch (e: Exception) {
//How do i return a status code here
}
} else {
//How do i return no internet here
return Exception(Constants.NO_INTERNET)
}
}

MyRetrofitInterface.kt

@POST("login/....")
fun loginRequest(@Body loginRequest: LoginRequest): Deferred<LoginResponse>?

我的问题是:

  1. 我的方法在架构上是否正确?
  2. 如何在我的代码中传递 http 错误代码或没有互联网连接
  3. 我的解决方案还有更好的方法吗?

最佳答案

在本地范围内启动协程是一个很好的做法,它可以在生命周期感知类中实现,例如 PresenterViewModel。您可以使用下一种方法来传递数据:

  1. 在单独的文件中创建 sealed Result 类及其继承者:

    sealed class Result<out T : Any>
    class Success<out T : Any>(val data: T) : Result<T>()
    class Error(val exception: Throwable, val message: String = exception.localizedMessage) : Result<Nothing>()
  2. 使 onUserLogin 函数可挂起并在 RepositoryInterfaceRepository 中返回 Result:

    suspend fun onUserLogin(loginRequest: LoginRequest): Result<LoginResponse> {
    return apiInterface.makeLoginCall(loginRequest)
    }
  3. APIInterfaceAPIInterfaceImpl中的makeLoginCall函数修改为如下代码:

    suspend fun makeLoginCall(loginRequest: LoginRequest): Result<LoginResponse> {
    if (isInternetPresent()) {
    try {
    val response = MyRetrofitInterface?.loginRequest(loginRequest)?.await()
    return Success(response)
    } catch (e: Exception) {
    return Error(e)
    }
    } else {
    return Error(Exception(Constants.NO_INTERNET))
    }
    }
  4. 为您的Presenter 使用下一个代码:

    class Presenter(private val repo: RepositoryInterface,
    private val uiContext: CoroutineContext = Dispatchers.Main
    ) : CoroutineScope { // creating local scope

    private var job: Job = Job()

    // To use Dispatchers.Main (CoroutineDispatcher - runs and schedules coroutines) in Android add
    // implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1'
    override val coroutineContext: CoroutineContext
    get() = uiContext + job

    fun detachView() {
    // cancel the job when view is detached
    job.cancel()
    }

    fun login() = launch { // launching a coroutine
    val request = LoginRequest()
    val result = repo.onUserLogin(request) // onUserLogin() function isn't blocking the Main Thread

    //use result, make UI updates
    when (result) {
    is Success<LoginResponse> -> { /* update UI when login success */ }
    is Error -> { /* update UI when login error */ }
    }
    }
    }

编辑

我们可以在 Result 类上使用扩展函数来替换 when 表达式:

inline fun <T : Any> Result<T>.onSuccess(action: (T) -> Unit): Result<T> {
if (this is Success) action(data)
return this
}
inline fun <T : Any> Result<T>.onError(action: (Error) -> Unit): Result<T> {
if (this is Error) action(this)
return this
}

class Presenter(...) : CoroutineScope {

// ...

fun login() = launch {
val request = LoginRequest()
val result = repo.onUserLogin(request)

result
.onSuccess {/* update UI when login success */ }
.onError { /* update UI when login error */ }
}
}

关于android - Kotlin 协程处理错误和实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54077592/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com