gpt4 book ai didi

Android (Kotlin) - 如何等待异步任务完成?

转载 作者:行者123 更新时间:2023-11-29 02:26:06 25 4
gpt4 key购买 nike

我是 Android 和 Kotlin 的新手,目前正在研究集中式 API 路由器类。为此,我使用了 Fuel Framework .对于 doAsync 函数,我使用 Anko for Kotlin图书馆。

要从我目前使用的 API 中检索授权 token :

 private fun Login(username: String, password: String, callback: (Map<Boolean, String>) -> Unit) {

"/auth/token.json".httpPost()
.header(mapOf("Content-Type" to "application/json"))
.body("""{"username":"$username", "password":"$password"}""", Charsets.UTF_8)
.response { request, response, result ->
request.headers.remove("Accept-Encoding")
when (result) {
is Result.Failure -> {

// val data = result.get()
val ex = result.getException()
val serverResponseJson = response.data.toString(Charsets.UTF_8)
var exceptionMessage = ex.message

val jelement = JsonParser().parse(serverResponseJson)
val jobject = jelement.asJsonObject

val serverResponseError = if (jobject.has("Error")) jobject.get("Error").asString else jobject.get("detail").asString


callback(mapOf(Pair(false, serverResponseError)))
}
is Result.Success -> {
val data = result.get()
val returnJson = data.toString(Charsets.UTF_8)
Log.println(Log.ASSERT, "RESULT_LOGIN", returnJson)

callback(mapOf(Pair(true, returnJson)))
}
}


}
}

我在

调用了这个登录方法
val btnLogin = findViewById<Button>(R.id.btn_login)
btnLogin.setOnClickListener { _ ->

doAsync {
val username = findViewById<EditText>(R.id.input_username_login)
val password = findViewById<EditText>(R.id.input_password_login)

Login(username.text.toString(), password.text.toString()) {

// Request was successful
if (it.containsKey(true)) {
// Parse return Json
// e.g. {"id":"36e8fac0-487a-11e8-ad4e-c471feb11e42","token":"d6897a230fd7739e601649bf5fd89ea4b93317f6","expiry":"2018-04-27T17:49:48.721278Z"}
val jelement = JsonParser().parse(it.getValue(true))
val jobject = jelement.asJsonObject

// save field for class-scope access
Constants.token = jobject.get("token").asString
Constants.id = jobject.get("id").asString
}
else{
Toast.makeText(this@LoginActivity, it.getValue(false), Toast.LENGTH_SHORT).show()
}
}
}[30, TimeUnit.SECONDS]

var test = Constants.id;

}

在一个单独的 Constants 类中,我像这样存储 token 和 ID:

class Constants {
companion object {
val baseUrl: String = "BASE_URL_TO_MY_API"

val contentTypeJson = "application/json"

lateinit var STOREAGE_PATH: String

// current user details
lateinit var id: String
lateinit var token: String
lateinit var refresh_token: String

// logged in User
lateinit var user: User
}

如何确保在异步任务完成后设置测试变量?目前,我遇到了

lateinit property id has not been initialized

我遇到了将任务限制为超时的选项,例如我对 [30, TimeUnit.SECONDS] 所做的,不幸的是,这没有帮助。

感谢您的帮助!干杯。

最佳答案

我认为问题出在你想访问结果的地方:

val btnLogin = findViewById<Button>(R.id.btn_login)
btnLogin.setOnClickListener { _ ->

doAsync {
val username = findViewById<EditText>(R.id.input_username_login)
val password = findViewById<EditText>(R.id.input_password_login)

var test: String? = null

Login(username.text.toString(), password.text.toString()) {

// Request was successful
if (it.containsKey(true)) {
// Parse return Json
// e.g. {"id":"36e8fac0-487a-11e8-ad4e-c471feb11e42","token":"d6897a230fd7739e601649bf5fd89ea4b93317f6","expiry":"2018-04-27T17:49:48.721278Z"}
val jelement = JsonParser().parse(it.getValue(true))
val jobject = jelement.asJsonObject

// save field for class-scope access
Constants.token = jobject.get("token").asString
Constants.id = jobject.get("id").asString
}
else{
Toast.makeText(this@LoginActivity, it.getValue(false), Toast.LENGTH_SHORT).show()
}
}

test = Constants.id // here test variable surely set if result was successful, otherwise it holds the null value
test?.let{
resultDelivered(it)
}

}[30, TimeUnit.SECONDS]

}

fun resultDelivered(id: String){
// here we know that the async job has successfully finished
}

关于Android (Kotlin) - 如何等待异步任务完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52123544/

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