Android for循环不循环?火基
我对以下代码有一个问题:我不明白为什么我的for循环在调用Android for循环不循环?火基,android,for-loop,firebase,firebase-realtime-database,Android,For Loop,Firebase,Firebase Realtime Database,我对以下代码有一个问题:我不明白为什么我的for循环在调用if(gameExists[0]==false){…之前不循环 Button playButton = (Button) findViewById(R.id.play_button); playButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) {
if(gameExists[0]==false){…
之前不循环
Button playButton = (Button) findViewById(R.id.play_button);
playButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
user = mFirebaseAuth.getCurrentUser();
final String gameCateg = String.valueOf(categorySelected[0]);
DatabaseReference allExistingGamesToMatchKeys = mFirebaseDatabase.getReference().child("gamestomatchkeys");
allExistingGamesToMatchKeys.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
final boolean[] gameExists = {false};
Log.d("gameExists before loop ", String.valueOf(gameExists[0]));
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
final String currentKey = postSnapshot.getKey();
//check player 2 is not the same as player 1 so that we don't match the same player
if(gameCateg.equals(postSnapshot.getValue().toString())){
mFirebaseDatabase.getReference().child("games").child(currentKey).child("player1").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String namePlayer1 = dataSnapshot.getValue(String.class);
if(!(user.getUid().toString().equals(namePlayer1))){
mFirebaseDatabase.getReference().child("gamestomatchkeys").child(currentKey).removeValue();
mFirebaseDatabase.getReference().child("games").child(currentKey).child("player2").setValue(user.getUid());
gameExists[0] = true;
Log.d("gameExists in for loop ", String.valueOf(gameExists[0]));
Intent intent = new Intent(getApplicationContext(), Game.class);
intent.putExtra("gameIdKey", currentKey);
startActivity(intent);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
break;
}
}
if (gameExists[0] == false){
Log.d("gameExists in if", String.valueOf(gameExists[0]));
这是我在日志中得到的信息,顺序如下:
循环之前存在游戏:false
游戏存在于if:false中
游戏存在于for循环中:true
我不明白为什么我会
游戏存在于if:false中
以前
游戏存在于for循环中:true
我希望在之前调用并完全循环我的循环如果(gameExists[0]==false){…
,我应该修改什么
谢谢!这是因为“gameExists in for loop”实际上不在for循环中,而是在for循环中创建的回调中
mFirebaseDatabase.getReference().child("games").child(currentKey).child("player1").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String namePlayer1 = dataSnapshot.getValue(String.class);
if(!(user.getUid().toString().equals(namePlayer1))){
mFirebaseDatabase.getReference().child("gamestomatchkeys").child(currentKey).removeValue();
mFirebaseDatabase.getReference().child("games").child(currentKey).child("player2").setValue(user.getUid());
gameExists[0] = true;
Log.d("gameExists in for loop ", String.valueOf(gameExists[0]));
Intent intent = new Intent(getApplicationContext(), Game.class);
intent.putExtra("gameIdKey", currentKey);
startActivity(intent);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
在这里,您正在创建ValueEventListener的新实例,并覆盖其中的方法。在实例化时,您没有在这些方法中执行代码。只要ValueEventListener决定调用onDataChange()方法,就会调用这些代码
我不完全确定这个物体是什么,或者它是如何工作的:
mFirebaseDatabase.getReference().child("games").child(currentKey).child("player1")
但如果我是你,我会先看看是否可以从中获得一个DataSnapshot,然后在你想在监听器之外执行的任何代码上使用该快照
如果非要我猜的话,可能有一种方法如下:
mFirebaseDatabase.getReference().child("games").child(currentKey).child("player1").getDataSnapshot();
然后将所有代码从onDataChange()内部复制到侦听器外部
(我不知道该方法是否存在,但我假设有某种方法可以获取当前的DataSnapshot)为了简单起见,Firebase数据库请求在代码流之外。请看以下内容:
// here is first point
allExistingGamesToMatchKeys.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// here is second point
}
...
}
// here is third point
上面的示例将这样执行
-->第一点-->第三点
那么第二个点在哪里?Firebase从在线数据库获取数据时,将执行第二个点,因此它在流程之外(但大多数情况下,它将在第三个点之后执行)
总之,如果您需要在Firebase请求完成后执行一些代码,请将其放入onDataChange()
你可以参考一下
我不确定是否理解:当侦听器附加到我的引用时调用onDataChange(),这是在我的for循环的开始和结束括号之间完成的。那么为什么它不应该是“循环的”?我需要在我的引用上有一个侦听器来获取值,没有“.getDataSnapshot()之类的内容。在这个侦听器中,我需要使用从for循环中获取的变量“currentKey”。没有
getDataSnapshot()
方法,如果要获取值,只能是addListenerForSingleValueEvent
或addValueEventListener()
谢谢,我了解它是如何工作的。在onDataChange中,我想调用我的“if”只有在我的列表被循环之后。所以我想我需要一个条件来说明这一点,比如if(这是DataSnapshot列表中的最后一个元素)或者if(DataSnapshot列表中的下一个元素为null)。我尝试了一些事情,比如if(currentKey==mFirebaseDatabase.getReference().child(“gamesotchkeys”).limitToLast(1.toString())但是我没有得到我想要的。你知道如何创建这样一个条件吗?最简单的方法是创建一个int
值,该值包含dataSnapshot
来自“gamesothitchkeys”
请求的计数,以及计数器的另一个int值。然后在onDataChange
中创建“games”
request,将计数器int乘以1。然后在相同的onDataChange
的最后一部分,比较第一个int值和计数器。如果匹配,则到达末尾