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

大鹏一日同风起,扶摇直上九万里。这篇文章主要讲述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 }


    推荐阅读