gpt4 book ai didi

android - Kotlin Coroutines如何实现正确调用api

转载 作者:行者123 更新时间:2023-12-05 05:57:48 27 4
gpt4 key购买 nike

嘿,我想从 object 类调用 api。我是协程的新手。我尝试了一些代码,但我不确定这样做是否正确。

  1. LoginHelper 中有一个叫做 logout 的函数,它有不止一个函数。我想先执行api调用。然后我想在注销中执行其他功能。

  2. Mainactivity 中,我调用 LoginHelper.logout 它会完成,然后我需要执行其他行。但我不想让挂起功能因为它也在使用其他地方。

还有一个错误过程:

com.dimen.app, PID: 12496
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1605)

session .kt

interface Session{
@DELETE("/session/delete")
fun deleteSession(): Call<Void>
}

SessionRepository.kt

suspend fun deleteSession(): RequestResult<Void> {
return apiCall(api.deleteSession())
}

RequestResult 是一个 Sealed Class

sealed class RequestResult<out T : Any> {
data class Success<out T : Any>(): RequestResult<T>
data class Error(): RequestResult<Nothing>()
fun result(success: (data: T?) -> Unit),error: (error: Error) -> Unit)
}

MainActivity.kt

private fun setupLogout() {
logoutButton.setOnClickListener {
LoginHelper.logout() // need to wait untill this finish
// more logic here....
}
}

LoginHelper.kt

object LoginHelper {

fun logout() {
logD("logout")
deleteSession() // need to wait untill this finish and then excute more function....
}

private fun deleteSession() {
runBlocking{
apiCall.deleteSession().execute()
}
}
}

最佳答案

永远不要在 Android 应用程序中使用 runBlocking,除非您确切地知道自己在做什么。 99% 的情况下这是错误的选择,因为它违背了使用协程的目的。阻塞意味着当前线程等待协程运行它的异步代码。但是您不能阻塞主线程,因为那样会卡住 UI。

由于您的 LoginHelper 是一个对象 或单例,如果它要启动协程,它需要自己的 CoroutineScope。

您可以使 deleteSession() 成为挂起函数,以便它可以调用 api.deleteSession() 挂起函数。

您可以让 logout() 启动协程以顺序删除 session 并随后执行其他任务。您可以让它返回已启动的作业,以便其他类可以选择是简单地启动注销,还是启动并等待协程中的注销。

object LoginHelper {
private val scope = CoroutineScope(SupervisorJob() + CoroutineName("LoginHelper"))

fun logout(): Job = scope.launch {
logD("logout")
deleteSession()
// .... more functions that happen after deleteSession() is complete
}

private suspend fun deleteSession() {
Tokenclass.getToken()?.let {
logE("token ::-> $it")
apiCall.deleteSession(it).execute()
}
}
}

如果您希望外部类能够等待logout 完成,它可以在自己的协程中对返回的Job 调用join(),因为示例:

logoutButton.setOnClickListener {
lifecycleScope.launch {
LoginHelper.logout().join()
// more logic here....
}
}

如果在 Activity 中不需要等待,就不需要启动协程,也不需要调用join()

关于android - Kotlin Coroutines如何实现正确调用api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68712809/

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