onChildRemoved()获取多次调用

问题描述:

我正在为我的android应用使用firebase数据库。我为其中一个firebase节点设置了ChildEventListener。当该节点的直接子节点被删除时,应该只是一次调用onChildRemoved(),但在我的情况下,它会被调用多次。onChildRemoved()获取多次调用

的原因,我觉得为什么发生这种情况是因为我已经把ChildEventListener在多个地方的同一节点在我的应用程序,因为当我把我的应用程序ChildEventListener一次,每胎删除onChildRemoved()方法被调用一次并如预期的那样。

片段A

firebaseData.child("patients").addChildEventListener(new ChildEventListener() { 

    @Override 
    public void onChildRemoved(DataSnapshot dataSnapshot) 
    { 
     dataChangedforListviewInFragmentA(dataSnapShot); 
    } 
}); 

片段B

firebaseData.child("patients").addChildEventListener(new ChildEventListener() { 

    @Override 
    public void onChildRemoved(DataSnapshot dataSnapshot) 
    { 
     dataChangedforListviewInFragmentB(dataSnapShot); 
    } 
}); 

片段C

firebaseData.child("patients").addChildEventListener(new ChildEventListener() { 

    @Override 
    public void onChildRemoved(DataSnapshot dataSnapshot) 
    { 
     dataChangedforListviewInFragmentC(dataSnapShot); 
    } 
}); 

在方法dataChangedforListviewInFragment()我使用更新后的数据设置了listView。 当节点patients的直接子节点被删除时,Fragment C中的onChildRemoved()被多次调用。

是否可以在我的应用程序的多个位置编写ChildEventListener,然后获取其回调方法以调用正确的次数。谢谢。

+0

下次,不要描述代码,请包括最小代码来重现问题中的问题。 –

+0

对不起,但这里没有最小编码。没有代码或许多代码会让问题变得直观。这个问题本身就很明显,如果你不清楚的话,如果需要的话,我会很乐意以更详细的方式解释。 –

当您将多个侦听器添加到同一位置时,将在相关事件发生时调用每个侦听器。

Firebase ref = new Firebase("https://docs-examples.firebaseio.com/web/saving-data/fireblog/posts"); 
// Create a listener 
ValueEventListener listener = new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot snapshot) { 
     System.out.println(snapshot.getValue()); 
    } 
    @Override 
    public void onCancelled(FirebaseError firebaseError) { 
    } 
}; 
// Attach listeners to read the data at our posts reference 
ref.addValueEventListener(listener); 
ref.addValueEventListener(listener); 

利用上述的设置,当posts的值改变时,收听者将被调用两次,新值将被打印的两倍。这正是应该发生的事情。

如果您只希望侦听器被调用一次,则只应将其添加到引用中。如果您已经添加了它,可以轻松完成。

boolean isListenerAdded = false; 
// then in the first place you'r adding a listener, the code will be executed 
if (!listenerAdded) { 
    ref.addValueEventListener(listener); 
    isListenerAdded = true; 
} 
// and in the other place, the code will be skipped 
if (!listenerAdded) { 
    ref.addValueEventListener(listener); 
    isListenerAdded = true; 
} 

如果侦听器在相同的片段/活动中,您可以将布尔值保留在活动的成员字段中。如果侦听器处于不同的活动中,则可以将SharedPreferences中的布尔值保留。但是在这种情况下,您应该在每个活动的onPause()中考虑removing the listeners

@Override 
public void onPause() { 
    super.onPause(); // Always call the superclass method first 

    if (listenerAdded) { 
     ref.removeEventListener(listener); 
    } 
} 
+0

我有三个听众分散在三个不同的片段中。我最好只设置一个监听器,但不能这样做,因为我使用监听器的值来设置每个片段中的listviews。如果我只在我的“片段A”中设置了一个监听器,那么来自那个听众也会进入其他两个片段,这会使代码变得复杂。尽管删除'onPause()'上的监听器应该可以帮助我。如果有更好的选择(设计模式)我的问题,请建议。谢谢。 –

+0

我没有看到问题。如果您有两个需要将相同数据添加到不同视图的地方,则使用两个听众听起来很完美。注意:如果这是一个问题,数据将只被检索一次。但如果不是,请考虑在问题中添加最少的问题再现,以帮助我理解问题。见http://stackoverflow.com/help/mcve –

+0

已经添加了一些代码的问题,请检查。 –