onChildRemoved()被多次调用

时间:2016-01-13 12:53:02

标签: android firebase

我正在为我的Android应用程序使用firebase数据库。我为其中一个firebase节点设置了ChildEventListener。当删除该节点的直接子节点时,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的直接子节点时,onChildRemoved()中的Fragment C被多次调用。

是否可以在我的应用中的多个位置编写ChildEventListener,然后让其回调方法被调用正确的次数。感谢。

1 个答案:

答案 0 :(得分:3)

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

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);
    }
}