局部变量在OnCompleteListener内部不会更改

时间:2018-09-20 03:04:22

标签: android kotlin

我在这里要做的是从数据库中获取所有需要的信息,并使用它来创建一个新的Account实例。但是,由于某种原因,在addOnCompleteListener部分结束后,名称,用户名等值不会更改。为什么会这样?

npm install --save semantic-ui

3 个答案:

答案 0 :(得分:0)

val acc = Account(uid,username,name,dob,email,tasks,friends)
println(acc.toString())
return acc

此代码在onCompleteListener上的内部代码之前执行。您应该在完成监听器中创建Account。当然,您不能从侦听器内部返回,因此将val acc设置为成员变量,而不是local。我不知道您的完整代码,因此不能对此提供太多建议。

答案 1 :(得分:0)

正在更改,只是当您期望它们更改时

更改方法签名以传递完成侦听器,并且不返回任何内容

private fun initlAccount(uid:String, listener:OnCompleteListener) {

   ...

   db.collection("users").document(uid).get().addOnCompleteListener(listener)
}  // End of method

将侦听器主体移到您调用此方法的位置,这会使它“回调”到另一个线程中,从而“返回执行结果”

注意:我不认识Kotlin,但是类似这样的东西

initlAccount("uid-value", OnCompleteListener { it ->
    if(it.isSuccessful){
        val result = it.result

        name = result.getString("Full name")!!
        username = result.getString("Username")!!
        dob = result.getString("Date of Birth")!!
        email = result.getString("Email")!!
        var arrtemp = result.get("Friends") as ArrayList<String>
        for(str in arrtemp){
            friends.add(initlAccount(str)) // Note: This is recursive, and will be an issue
        }
        arrtemp = result.get("Tasks") as ArrayList<String>
        tasks = getTasks(arrtemp)
        val acc = Account(uid,username,name,dob,email,tasks,friends)
        println(acc.toString())

        // Your account is returned here, so you can update a UI element, for example
    }
}) // end initlAccount method call

// do NOT use acc here, it will be unassigned or null 

我看到您正在进行递归调用,因此您应该使数据库查询本身具有自身的句柄,以便客户端不会处于无休止的循环中(“友谊”应该是自反的-userA是userB的朋友,因此获得userB的帐户将返回到获得userA的朋友,然后继续),或者您可以尝试研究RxJava / Kotlin flatMap运算符。

答案 2 :(得分:0)

与其创建返回Account的方法。

  

为什么不直接查询以获取Account?因为这样做会导致工作流程不同步。

   db.collection("users").document(uid).get().addOnCompleteListener {
        if(it.isSuccessful){
            name = it.result.getString("Full name")!!
            username = it.result.getString("Username")!!
            dob = it.result.getString("Date of Birth")!!
            email = it.result.getString("Email")!!
            var arrtemp = it.result.get("Friends") as ArrayList<String>
            for(str in arrtemp){
                friends.add(initlAccount(str))
            }
            arrtemp = it.result.get("Tasks") as ArrayList<String>
            tasks = getTasks(arrtemp)

            val acc = Account(uid,username,name,dob,email,tasks,friends)
            println(acc.toString())
            // Probably do a save in Database?
        }
    }