大鹏一日同风起,扶摇直上九万里。这篇文章主要讲述Android(Kotlin) - 如何等待异步任务完成?相关的知识,希望能为你提供帮助。
我是android和Kotlin的新手,目前正在开发集中式API路由器类。为了达到这个目的,我使用的是Fuel Framework。对于doAsync函数,我使用Anko for Kotlin库。
要从API检索授权令牌,我目前使用此方法:
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 = https://www.songbingjia.com/android/result.get()
val ex = result.getException()
val serverResponseJson = response.data.toString(Charsets.UTF_8)
var exceptionMessage = ex.messageval jelement = JsonParser().parse(serverResponseJson)
val jobject = jelement.asJsonObjectval serverResponseError = if (jobject.has("Error")) jobject.get("Error").asString else jobject.get("detail").asStringcallback(mapOf(Pair(false, serverResponseError)))
}
is Result.Success ->
{
val data = https://www.songbingjia.com/android/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类中,我存储令牌和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
}
如何在异步任务完成后确保设置测试变量?目前,我遇到了
【Android(Kotlin) - 如何等待异步任务完成()】lateinit属性id尚未初始化我遇到了将任务限制为超时的选项,例如我使用[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? = nullLogin(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 AsyncTask问题(连接到Web服务)
- E / AndroidRuntime(致命异常:Android的AsyncTask#1 ERROR)
- Android AsyncTask无法运行
- AsyncTask在android中加载数据的次数非常不同
- Android Socket,AsyncTask,Handler内存泄漏
- 示例(使用AsyncTask的Android双向网络套接字)
- 如何在没有AppEngine for Google云端存储的情况下获取服务网址()
- 带有Gcloud错误的Rails((gcloud.preview.app.deploy)错误响应:[13]意外错误。部署版本:)
- 仅包含日期和月份的Android日期选择器