2016-01-13 91 views
0

我正在爲我的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

對不起,但這裏沒有最小編碼。沒有代碼或許多代碼會讓問題變得直觀。這個問題本身就很明顯,如果你不清楚的話,如果需要的話,我會很樂意以更詳細的方式解釋。 –

回答

1

當您將多個偵聽器添加到同一位置時,將在相關事件發生時調用每個偵聽器。

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

已經添加了一些代碼的問題,請檢查。 –