Java removeEventListener未在firebase中删除侦听器

Java removeEventListener未在firebase中删除侦听器,java,firebase,firebase-realtime-database,Java,Firebase,Firebase Realtime Database,当特定字段的值为true时,我想从firebase引用中删除addValueEventListener侦听器 ValueEventListener valueListener=null; private void removeListener(Firebase fb){ if(valueListener!=null){ **fb.removeEventListener(valueListener);** } } String key="https://boil

当特定字段的值为true时,我想从firebase引用中删除addValueEventListener侦听器

ValueEventListener valueListener=null;

private void removeListener(Firebase fb){
    if(valueListener!=null){
        **fb.removeEventListener(valueListener);**
    }
}

String key="https://boiling-heat-3083.firebaseio.com/baseNodeAttempt/" + userId+"/"+nodeType+"/"+nodeId+"/data";
final Firebase fb = new Firebase(key);
valueListener=fb.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot snap) {
        final HashMap<String, Object> data=(HashMap<String, Object>) snap.getValue();
        if( data.get("attemptFinish_"+nodeId)!=null){
            boolean title = (boolean) snap.child("attemptFinish_"+nodeId).getValue();
            if(title){
                removeListener(fb);
            }
        }
    }
    @Override
    public void onCancelled() {
        // TODO Auto-generated method stub
    }
});
ValueEventListener-valueListener=null;
专用无效清除器(Firebase fb){
if(valueListener!=null){
**fb.removeEventListener(valueListener)**
}
}
字符串键=”https://boiling-heat-3083.firebaseio.com/baseNodeAttempt/“+userId+”/“+nodeType+”/“+nodeId+”/data”;
最终Firebase fb=新Firebase(键);
valueListener=fb.addValueEventListener(新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot快照){
最终HashMap数据=(HashMap)snap.getValue();
if(data.get(“attemptFinish”+nodeId)!=null){
boolean title=(boolean)snap.child(“attemptFinish”+nodeId).getValue();
如果(标题){
重组监听器(fb);
}
}
}
@凌驾
已取消的公共无效(){
//TODO自动生成的方法存根
}
});

但是addValueEventListener没有被删除,它是为firebase引用调用的。因此,如果需要,请建议我如何从任何firebase引用中删除侦听器。

您可以使用以下方法从回调中删除侦听器:

ref.removeEventListener(this);
这是一个完整的片段:

String key="https://boiling-heat-3083.firebaseio.com/baseNodeAttempt/" + userId+"/"+nodeType+"/"+nodeId+"/data";
final Firebase ref = new Firebase(key);
ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot snap) {
        if (snap.hasChild("attemptFinish_"+nodeId) {
            boolean isFinished = (boolean) snap.child("attemptFinish_"+nodeId).getValue();
            if(isFinished){
                ref.removeEventListener(this);
            }
        }
    }
    @Override
    public void onCancelled() {
        // TODO Auto-generated method stub
    }
});

我删除了
HashMap
,而是使用
DataSnapshot
的方法来完成同样的操作。我还重命名了一些变量,以使其更清晰/更惯用。

确保将侦听器添加和删除到数据库引用上的同一节点。例如:

//when declared like this, mDatabaseReference will point to the parent node by default
private DatabaseReference mDatabaseReference = FirebaseDatabase.getInstance().getReference();;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

//listener added to child node "path_2"
mDatabaseReference.child(path_1).child(path_2).addChildEventListener(myListener); 
}
您的侦听器是这样的:本例指向路径2。 如果您试图使用此代码删除侦听器

//mDatabaseReference pointing to parent node (default behaviour)
mDatabaseReference.removeEventListener(myListener);
它无法工作,因为您试图从错误的节点删除侦听器。正确的方法是

mDatabaseReference.child(path_1).child(path_2).removeEventListener(myListener);

我希望这能帮助你。。。只要你能用这个方法,对我来说很有用

private DatabaseReference dbRef;
从onCreate()写入

从onDestroy()写入

听众

 private void InitListener(String templeId) {
    valueEventListener=new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {


        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };

}

您的
valueListener
始终为
null
您可以使用
if(title){fb.removeEventListener(this);}
从回调中删除侦听器。无关:此代码的大多数读者都认为
title
是一个字符串。您可能希望使用一个更直观的变量名,将其解释为布尔值,例如,
isFinished
。添加侦听器时,valueListener有一个引用@talexi have thread,但使用上面的代码@Frank van PuffelenDid无法删除侦听器您在调试器中运行的吗?如果是这样的话,
isFinished是否曾经
true`?是的,它是true,如果ref.removeEventListener(this)上面的语句得到executed@FrankvanPuffelen,如果我调用ref.removeEventListener(this);在}之前的onDataChange结束时。。。可以吗?我试过了,它在我的项目中起了作用。你为什么要用isFinished?嗨,谢谢。你的解决方案对我有效。使用LeakCanary后,它检测到内存泄漏。通过在完成数据提取后删除侦听器(在ValueEventListener()中),内存泄漏停止。虽然我没有工作,但我也发现了这个错误
if (dbRef!=null){
        dbRef.removeEventListener(valueEventListener);
        valueEventListener=null;
        dbRef=null;

    }
 private void InitListener(String templeId) {
    valueEventListener=new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {


        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };
private DatabaseReference dbRef;
ValueEventListener mSendEventListner;

dbRef = FirebaseDatabase.getInstance().getReference().child("users").child(phone);

ValueEventListener valueEventListener = new ValueEventListener() 
{
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists())
                {              
                   //
                } 
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                //
            }
};
dbRef.addValueEventListener(valueEventListener);
mSendEventListner = valueEventListener;


//REMOVE VALUE EVENTLISTNER...
@Override
protected void onDestroy() 
{
    super.onDestroy();
    if (mSendEventListner != null) {
        dbRef.removeEventListener(mSendEventListner);
    }
}