【问题标题】:removeEventListener not removing listener in firebaseremoveEventListener 未删除 firebase 中的侦听器
【发布时间】:2015-09-07 19:12:21
【问题描述】:

当特定字段的值为 true 时,我想从 firebase ref 中删除 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
    }
});

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

【问题讨论】:

  • 您的valueListener 始终是null
  • 您可以使用if (title) { fb.removeEventListener(this); } 从回调中删除监听器。无关:这段代码的大多数读者会认为title 是一个字符串。您可能希望使用更直观的变量名称来解释为布尔值,例如isFinished.
  • valueListener 在添加监听器时有一个引用@talex

标签: java firebase firebase-realtime-database


【解决方案1】:

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

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 的方法来完成相同的操作。我还重命名了一些变量,使其更清晰/更惯用。

【讨论】:

  • 我已经尝试过,但使用上面的代码@Frank van Puffelen 没有删除监听器
  • 您是否在调试器中运行过?如果是,是isFinished ever true`?
  • 是的,如果上面的 ref.removeEventListener(this) 语句被执行,它是真的并且记录在里面
  • @FrankvanPuffelen,如果我调用 ref.removeEventListener(this);在 onDataChange 的末尾,就在 }... 之前可以吗?我试过了,它适用于我的项目。您使用 isFinished 有什么原因吗?
  • 嗨,谢谢。你的解决方案对我有用。使用 LeakCanary 后,它检测到内存泄漏。并且通过在完成获取数据后移除监听器(在 ValueEventListener() 中),内存泄漏停止。谢谢
【解决方案2】:

确保将侦听器添加和删除到 DatabaseReference 上的同一节点。例如:

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

您的侦听器在这种情况下指向 path_2。 如果您尝试使用此代码删除您的侦听器

//mDatabaseReference pointing to parent node (default behaviour)
mDatabaseReference.removeEventListener(myListener);

它不起作用,因为您试图从错误的节点中删除侦听器。正确的方法是

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

【讨论】:

  • 虽然不适合我但是我也发现了这个错误
【解决方案3】:

我希望这会对你有所帮助......只是你可以使用这个方法,它对我有用......

private DatabaseReference dbRef;

从 onCreate() 写入

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    dbRef= database.getReference("YOUR_PATH").child("KEY_NAME");
    InitListener();
    dbRef.addValueEventListener(valueEventListener); // ADDIND_LISTENER

从 onDestroy() 写入

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) {

        }
    };

}

【讨论】:

    【解决方案4】:
    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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 2019-01-24
      • 2014-02-27
      • 2022-08-03
      • 2021-08-13
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 2017-03-16
      相关资源
      最近更新 更多