0

I have a function that add custom listeners to the same trigger event.

So the same event can trigger multiple listeners, this is working. What I would like is: if I have 3 listeners (for example) be able to remove just one of then and let the other two working.

This is my function to add events, they are in a Map<String, CustomListener> variable.

void addEventListener(String eventName, EventListener eventListener) {
    List<eventListener> eventListenerList = new ArrayList<>();

    if (eventListenerMap.containsKey(eventName)) {
        eventListenerList = eventListenerMap.get(eventName);
    }
    Objects.requireNonNull(eventListenerList).add(eventListener);
    eventListenerMap.put(eventName, eventListenerList);
}

And this is my function to remove

void removeEventListener(String eventName, EventListener eventListener) {
    if (eventListenerMap.containsKey(eventName)) {
        List<InsEventListener> eventListenerList = eventListenerMap.get(eventName);
        assert eventListenerList != null;
        eventListenerList.remove(eventListener);

        eventListenerMap.put(eventName, eventListenerList);
    }
    else {
        Log.w("Remove Event Listener:", "Event not found");
    }
}

As you can see in the image below, it recognise the same class with the same lamba address, but it won't remove.

enter image description here

Obs: all the listeners are called in the same function in the same place

Canato
  • 3,598
  • 5
  • 33
  • 57

1 Answers1

1

That's because eventListenerList.remove(eventListener.getClass()); isn't removing anything. You aren't suppose to remove your listeners by their class, but by index or by a method that distinguishes them one from another.
If you checked the remove() return value you would get false, which means the parameter wasn't in that list. oracle documentation.

In general an object can be removed in two ways from an ArrayList (or generally any List), by index (remove(int)) and by object (remove(Object)). reference here

What you need to do:

Add an equals(Object) method to your EventListener class. That will allow you to do eventListenerList.remove(eventListener) to identify the correct object.

I think the simplest thing to do is to add a name or id attribute to your Parent class that will be unique between all of your listeners, and override equals that checks for those attributes.

You can easily generate equals(object) method with Android Studio IDE, press Ctrl + O and choose the equals method.

EDIT:

I suggest two options for handling IDs for your listeners:

  1. Generate the ID yourself in addEventListener and return it to the caller, store the listener in a map instead of list, the key is the ID. When someone wants to remove a listener, he will send the generated ID and you will remove it from the Event's listeners map.
  2. Generate the ID yourself in addEventListener and save it in an EventListener ID attribute that cannot be changed by anyone else. Then, to remove a specific listener, you only need to implement an equals methods that checks the ID attribute.
ronginat
  • 1,910
  • 1
  • 12
  • 23
  • You are right, .getclass was just a test that I forgot to remove. But without, just passing the listener object, don't work too. I will check this .equals option. The ID option is not good because it will be used for other developers who sound not worry about it. But thanks for the inside. – Canato Mar 25 '19 at 13:07