我一直在使用firebase,我注意到一些奇怪的事情。 我在活动中注册的一个值事件监听器即使在我完成活动后也会被触发。 我添加了代码以在'onDataChanged'方法中打开一个新活动,所以即使我在不同的活动中,也会打开新活动。这导致应用程序出现大问题。 我知道我必须调用remove listener但我希望在活动结束后自动删除监听器。有没有更简单的方法可以删除活动的所有值事件侦听器?提前谢谢。
答案 0 :(得分:4)
离开主活动后,您需要删除侦听器。为此,您可以创建一个这样的方法:
private HashMap<DatabaseReference, ValueEventListener> hashMap = new HashMap<>();
public static void removeValueEventListener(HashMap<DatabaseReference, ValueEventListener> hashMap) {
for (Map.Entry<DatabaseReference, ValueEventListener> entry : hashMap.entrySet()) {
DatabaseReference databaseReference = entry.getKey();
ValueEventListener valueEventListener = entry.getValue();
databaseReference.removeEventListener(valueEventListener);
}
}
每次要删除列表器时,都可以使用以下代码行:
hashMap.put(yourRef, eventListener);
根据活动生命周期调用removeValueEventListener(hashMap);
。您可以在onPause()
或onStop()
方法中添加此行。通过这种方式,您可以立即删除所有侦听器。
希望它有所帮助。
答案 1 :(得分:0)
还有其他方式
mReference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
//Your initial code:
.....
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
mReference.removeEventListener(this);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
mReference.removeEventListener(this);
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
mReference.removeEventListener(this);
}
@Override
public void onCancelled(DatabaseError databaseError) {
mReference.removeEventListener(this);
}
});
不是说这是最好的方法,但它帮助我解决了问题
答案 2 :(得分:0)
对于那些像我这样开始使用Android Studio但又不立即理解Alex Mamo的答案的人,这里有一个简短的示例:
首先声明您的Firebase和HashMap变量,如下所示。
private DatabaseReference NotifyGroupRef;
private ValueEventListener valueEventListener;
private HashMap<DatabaseReference, ValueEventListener> groupCreatorAndKeys = new HashMap<>();
之后,在 onCreate 中分配您的Firebase参考,如下所示。
NotifyGroupRef = FirebaseDatabase.getInstance().getReference().child("NotifyGroup");
创建一个函数以添加您的侦听器,如下所示。
private void updateNotifyGroupInternet(String groupCreator, String groupKey) {
NotifyGroupRef.child(groupCreator).child(groupKey).addValueEventListener(valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String[] splittedSnapshot = dataSnapshot.getValue().toString().split("=");
String clientId = splittedSnapshot[0].replace("{","");
String notification = splittedSnapshot[1].replace("}", "");
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
groupCreatorAndKeys.put(NotifyGroupRef.child(groupCreator).child(groupKey), valueEventListener);
}
在启动如下所示的新活动时,停止收听。
@Override
public void onPause() {
super.onPause();
for (Map.Entry<DatabaseReference, ValueEventListener> entry : groupCreatorAndKeys.entrySet()) {
DatabaseReference databaseReference = entry.getKey();
ValueEventListener value = entry.getValue();
databaseReference.removeEventListener(value);
}
}
最后,按下返回按钮返回活动时,再次添加侦听器,例如:
@Override
public void onStart() {
super.onStart();
for (Map.Entry<DatabaseReference, ValueEventListener> entry : groupCreatorAndKeys.entrySet()) {
DatabaseReference databaseReference = entry.getKey();
ValueEventListener value = entry.getValue();
databaseReference.addValueEventListener(value);
}
}
在我的示例中,我通过变量groupCreator
和groupKey
使用了不同的路径,效果很好!