Shahid Shaikh
Shahid Shaikh

Reputation: 117

How do I remove this listener in OnDestroy (Android Firebase)?

This is my ValueEventListener in OnCreate method. I want to destroy this is OnDestroy method because it might be causing memory leak and also I've read it that it's a good practice to do so.

mDatabase.child(mPost_key).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            display_author = (String) dataSnapshot.child("author").getValue();
            display_quote = (String) dataSnapshot.child("quote").getValue();
            display_pic_url = (String) dataSnapshot.child("pic_url").getValue();
            categoryData=(String) dataSnapshot.child("catg").getValue();
            display_prof=(String) dataSnapshot.child("prof").getValue();
            copyQuote = (display_quote + " - " +display_author);
            try {
                author.setText(display_author);
                quote.setText(display_quote);
                category.setText(categoryData);
                profession.setText(display_prof);
                Glide.with(SingleExploreQuotes.this).load(display_pic_url).override(192, 192).into(profile_img);

            } catch (Exception e) {
                finish();
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

Upvotes: 7

Views: 12982

Answers (6)

AL.
AL.

Reputation: 37798

To copy Firestore's ListenerRegistration behavior and have the same seamless implementation, I implemented a custom class named ListenerRegistration as well, that accepts a DatabaseReference and a listener object, that is either a ChildEventListener or ValueEventListener.

import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ValueEventListener;

import org.jetbrains.annotations.NotNull;

public class ListenerRegistration {

    private DatabaseReference mDatabaseReference;
    private Object mListener;

    ListenerRegistration(@NotNull DatabaseReference databaseReference,
                         @NotNull Object listener) {
        if (listener instanceof ChildEventListener || listener instanceof ValueEventListener) {
            mDatabaseReference = databaseReference;
            mListener = listener;
        } else {
            throw new IllegalArgumentException("Listener type invalid");
        }
    }

    public void remove() {
        if (mListener instanceof ChildEventListener) {
            mDatabaseReference.removeEventListener((ChildEventListener) mListener);
        } else if (mListener instanceof ValueEventListener) {
            mDatabaseReference.removeEventListener((ValueEventListener) mListener);
        } else {
            throw new IllegalArgumentException("Listener type invalid");
        }
    }

}

This way, every time I attach a listener, I just keep the value and then call .remove() as needed. e.g.

ValueEventListener listener = {...}
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference(NODE_ROOT).child(NODE_SAMPLE);
ListenerRegistration lr = new ListenerRegistration(dbRef, listener);

then somewhere like onDestroy():

lr.remove()

Upvotes: 2

Edward DiGirolamo
Edward DiGirolamo

Reputation: 762

For those looking for the Firebase Firestore version of this answer Use ListenerRegistration and then call .remove() on it in onDestroy()

private ListenerRegistration listenerRegistration;

listenerRegistration = Reference.addsnapshotListener(new 
EventListener<QuerySnapshot>){
  @Override
        public void onEvent(QuerySnapshot documentSnapshots, 
        FirebaseFirestoreException e) {
         //get your data

  }
});


@Override
protected void onDestroy() {
    super.onDestroy();

    if(listenerRegistration != null) {
        listenerRegistration.remove();
    }

}

Upvotes: 0

sabith.ak
sabith.ak

Reputation: 255

With reference of @Frank van Puffelen's answer. Change code to:

private ValueEventListener mListener;
mListener = mDatabaseRef.addValueEventListener(new ValueEventListener() 
{...}

in onDestry() :

@Override
    protected void onDestroy() {
        super.onDestroy();
        mDatabaseRef.removeEventListener(mListener);
    }

Upvotes: 3

Frank van Puffelen
Frank van Puffelen

Reputation: 599601

When you register the listener, you get back a handle to the listener. Keep that listener in a member field:

private ValueListener mListener;

mListener = mDatabase.child(mPost_key).addValueEventListener(new ValueEventListener() {

And then remove the listener in your onDestroy():

mDatabase.child(mPost_key).removeListener(mListener);

Upvotes: 15

Sasi Kumar
Sasi Kumar

Reputation: 13348

you can Remove any listener using removeEventListener method .you faced memory leak issues so clear memory of your Glide library in ondestroy like this

@Override 
public void onDestroy() {
super.onDestroy();
//removelistener
mDatabase.child(mPost_key).removeEventListener(ValueEventListener);
Glide.get(this).clearMemory();//clear memory

}

Upvotes: 0

Mavya Soni
Mavya Soni

Reputation: 972

Just put below code in onDestroy()

@Override
protected void onDestroy() {
    super.onDestroy();
    if(!isFinishing()){
    mDatabase.child(mPost_key)..addValueEventListener(null);
  }
}

Upvotes: 0

Related Questions