Android 当使用假定为真的条件时,我的Kotlin for循环不会中断

Android 当使用假定为真的条件时,我的Kotlin for循环不会中断,android,for-loop,kotlin,break,Android,For Loop,Kotlin,Break,我已经尝试解决这个问题好几天了,但一无所获。所以,我有一个我正在开发的小Android应用程序(对Kotlin和Android Dev来说还是很新的),用于注册并向Firebase实时数据库添加密码和用户名。数据库中的所有内容都有一个数字键,有点像数字1将被设置为用户名和相应的密码,数字2也将有用户名和密码的值,依此类推。因此,我创建了这个for循环,它从1的键开始,检查每个数字键是否已经分配给。如果当前值尚未分配给,则会在其中存储新的用户名和密码,当单击“注册”按钮时,循环将中断 作为该循环工

我已经尝试解决这个问题好几天了,但一无所获。所以,我有一个我正在开发的小Android应用程序(对Kotlin和Android Dev来说还是很新的),用于注册并向Firebase实时数据库添加密码和用户名。数据库中的所有内容都有一个数字键,有点像数字1将被设置为用户名和相应的密码,数字2也将有用户名和密码的值,依此类推。因此,我创建了这个for循环,它从1的键开始,检查每个数字键是否已经分配给。如果当前值尚未分配给,则会在其中存储新的用户名和密码,当单击“注册”按钮时,循环将中断

作为该循环工作原理的示例:假设“1”的用户名为“11111”,密码为“11111”,“2”的用户名为“22222”,密码为“22222”,3为空。当for循环到达键3时,它将有一个用户名“33333”和一个密码“333333”,而另一个键的值都没有改变。然而,问题是我已经用10个值测试了它,在设置了值之后,它只是将设置的值保持在我要求它设置的值之外。我相信这是因为下面for循环末尾的条件。我想存储变量中的数据是否已更改,并在以后使用它,但这无法正常工作。我通过在if语句中插入“true”来测试这一点,它会中断,但在使用变量时,它不会中断

这是我的循环:

      var dataHasBeenSet : Boolean = false
      for(num in 1..10){
           database.child(num.toString()).get().addOnSuccessListener {
               if(it.value == "" || it.value == null || it.value == "null") {
                        database.child(num.toString()).setValue(AccountAdder(password.text.toString(), username.text.toString()))
                        dataHasBeenSet = true
                    } else {
                        dataHasBeenSet = false
                        //Runs again
                    }
                }.addOnFailureListener {
                    Toast.makeText(this, "Database cannot be reached at this time. Please try again later", Toast.LENGTH_LONG).show()
                }
                //Conditional works, however the condition statement does not. Why?
                if(dataHasBeenSet){
                    break
                } else {
                    continue
                }
            }
是的,数据实际上是被设置的,但是循环的行为就像dataHasBeenSet变量没有被设置为true一样,即使我已经将其重新分配为true。请记住,底部的条件是有效的,因为我在默认情况下插入了true,但是看起来dataHasBeenSet变量的值永远不会更改,即使数据被添加到数据库中

我所尝试的:

  • 初始化循环中的变量
  • 将中断条件放在循环的顶部
  • 将条件更改为与所需结果相反的情况

这件事上的任何帮助都会让这场噩梦结束!谢谢大家!

您需要在
addOnSuccessListener
的回调中移动条件,在firebase查询后台线程结束时触发
OnSuccessListener
回调时,将不会触发获取条件

另一个问题是for循环在主线程中运行,而firebase方法在工作线程中运行,因此这里您希望中断/继续来自不同线程的迭代

我得到错误:“break”或“continue”跨越函数或类边界

这是因为您试图从firebase回调的lambda中返回,而编译器不确定它应该返回到哪里

我鼓励您改变使用循环的方法,使用监听器接口,每当您想要重复循环时(即每当dataHasBeenSet时),都会调用其回调。。但实际上,在这种方法中,您不需要使用布尔值
dataHasBeenSet
,只需使用新的迭代值调用侦听器回调

创建此界面:

interface NextCallListener {
    fun onNext(num: Int)
}
在周围的类中实现它,我将假定它的名称为
MainActivity

class MainActivity: AppCompatActivity() , NextCallListener {
    
}
然后将firebase代码移动到接受迭代编号的新方法和侦听器实例中:

fun nextCall(num: Int, listener: NextCallListener) {
    database.child(num.toString()).get().addOnSuccessListener {
        if (it.value == "" || it.value == null || it.value == "null") {
            database.child(num.toString())
                .setValue(AccountAdder(password.text.toString(), username.text.toString()))
            if (num <= 10)  // loop max value
                listener.onNext(num + 1) // trigger the interface callback for the next iteration
        }
    }.addOnFailureListener {
        Toast.makeText(
            this,
            "Database cannot be reached at this time. Please try again later",
            Toast.LENGTH_LONG
        ).show()
    }

}
并实现接口回调:

class MainActivity: AppCompatActivity() , NextCallListener {
    
    override fun onNext(num: Int) {
        nextCall(num, this)
    }
}

Firebase调用是异步的(这是一个网络调用,所以这很直观,不能是即时的),所以它不会在下一行完成。请记住,您并不是在该行的侦听器中运行代码,而是在网络请求成功/失败时附加要运行的代码。如果希望侦听器在请求完成时运行,则应将逻辑放在侦听器中。我曾尝试过这样做并进行编译,但我得到的错误是“break”或“continue”突破了函数或类边界是的,您不能中断循环,因为代码是异步运行的,因此,当您收到回调(可能)时,循环已经完成。您可以将其封装在以数字为参数的方法中,然后在请求完成时递归调用它。然而,您可能想完全重新思考您的方法,它似乎很复杂。我刚刚尝试了这个方法并进行了编译,但是我得到了错误:“break”或“continue”在函数或类中中断boundary@ToxicFlame427请检查更新的答案,我刚刚改变了方法。非常感谢!起初,当我运行它时,它所做的事情与我编写的代码相同。所以我仔细看了一下,发现我需要把if(num Good job executes)放在我没有机会测试的地方。如果你觉得这样回答了你的问题,请点击左边的勾号接受答案
class MainActivity: AppCompatActivity() , NextCallListener {
    
    override fun onNext(num: Int) {
        nextCall(num, this)
    }
}