johncarl81 / transfuse

:syringe: Transfuse - A Dependency Injection and Integration framework for Google Android
http://androidtransfuse.org/
Apache License 2.0
220 stars 28 forks source link

Event observers in singleton are registered multiple times #157

Open goodsoft opened 9 years ago

goodsoft commented 9 years ago

Consider the following situation:

@Application
class App {
    @Inject Library lib;
}
@Activity
class Main {
    @Inject Library lib;
}
@Singleton
class Library {
    @Observes
    void onEvent (SomeEvent event) {
        // handle event
    }
}

In this situation event observer is registered and executed twice. And each injection in each component registers yet another observer.

I've looked through generated code and I think the best way to solve this problem is to register observers for singletons not in component's onCreate method, but in singleton's ...$$UnscopedProvider.get method. This would also solve the problem of observers' persistence between different activities, services etc

johncarl81 commented 9 years ago

Where are you triggering the event from?

goodsoft commented 9 years ago

From entirely different object, instantiated by Library

johncarl81 commented 9 years ago

I mean, where are you calling EventManager.trigger(someEvent)? From the App or Main class?

goodsoft commented 9 years ago

I mean exactly that. There is an object of class, let's say, Socket, which is created in Library and then calls eventManager.trigger(someEvent). The onEvent method is then called the same amount of times as the number of currently active (onResume called) components, which inject Library (i.e. current activity, application, several fragments)

johncarl81 commented 9 years ago

Ah, ok, I understand and you are probably right. Not sure what the fix would be immediately, but I do like your idea about registering the observer in the Provider.

johncarl81 commented 9 years ago

@goodsoft, in case it wasn't obvious, the stop-gap solution would be the following:

@Application
class App {
    @Inject Library lib;

    @Observes
    void onEvent (SomeEvent event) {
        lib.onEvent(event);
    }
}
@Activity
class Main {
    @Inject Library lib;
}
@Singleton
class Library {
    void onEvent (SomeEvent event) {
        // handle event
    }
}

... until we have a better solution for this