![](/img/trans.png)
[英]Android - How listener object is not destroyed even after the method is finished?
[英]Firebase value event listener firing even after activity is finished?
我一直在使用 firebase,我注意到一些奇怪的事情。 即使我完成了活动,我在活动中注册的价值事件侦听器之一也会被触发。 我在'onDataChanged' 方法中添加了用于打开新活动的代码,因此即使我处于不同的活动中,也会打开新活动。 这在应用程序中造成了大问题。 我知道我必须调用 remove listener,但我希望在活动完成后会自动删除侦听器。 有没有更简单的方法可以删除活动的所有值事件侦听器? 提前致谢。
离开主要活动后,您需要删除侦听器。 为此,您可以创建这样的方法:
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()
方法中添加此行。 通过这种方式,您可以一次删除所有侦听器。
还有一点点其他方式
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);
}
});
不是说这是最好的方法,但它帮助我解决了问题
对于那些像我一样开始使用 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
使用了不同的路径,并且效果很好!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.