Comments (12)
See @JakeWharton's answer in the G+ thread at https://plus.google.com/106183159594179737258/posts/1rzvYZSF7zm
"We never unregister singletons. They stay on the bus until the process dies."
"We don't like registering things in their constructor."
Jake mentioned to post a "gist about some Dagger trickery" they use. I'm also still waiting eagerly for it. :)
from otto.
Thanks. He also mentioned that some thing will come in release 2.0. Unfortunately the last commit was 3 months ago 😢
from otto.
It'd be great if Otto supported registering with a WeakReference so you could safely register POJO's or classes like Android Adapters that don't themselves know how long their lifecycle should be.
from otto.
We tried that. It was a horrible anti-pattern.
from otto.
@JakeWharton how so?
from otto.
Everything that needs to register and unregister is either connected to a lifecycle directly or completely disconnected (and thus never unregisters). A weak reference is either just being lazy and not wanting to properly tie registration to a lifecycle or you are not in proper control of a lifecycle and are guessing when you think unregistration should occur.
In the example above the adapter doesn't have a direct lifecycle but it's bound to that of the view to which it is attached. The fact that you want unregistration at all implies there is a lifecycle.
from otto.
Isn't it as much of an anti-pattern to leak every object that subscribes? Wouldn't it be cleaner to just wrap every subscriber in a WeakReference
? That would handle both the POJO case and missed calls to unregister
. And callers could still explicitly register and unregister on appropriate state changes within their lifecycle.
from otto.
I'd argue that there's no need for strong references to registered objects in an event bus, ever. An event bus should never be used to keep an object alive and in memory.
Of course changing Otto to use weak references could present backwards compatibility issues for users that do use it to keep objects alive but adding a new registerWeak method that then wraps the object in a WeakReference would work for everyone and give you the power to choose.
I'd just like to gauge whether there'd be any openness towards a pull request. If not, that's fine, I'll drop it.
from otto.
Isn't it as much of an anti-pattern to leak every object that subscribes?
Yes it is. So call unsubscribe on them. The Bus is a mechanism for leaking an object not a leak itself.
An event bus should never be used to keep an object alive and in memory.
You are right. That is why you must unsubscribe after the object should stop receiving calls to ensure that it can be garbage collected.
The Bus is a strong coupling and it is your responsibility to manage subscription to it. We are not interested in making the references weak because it falsely absolves your from your responsibility. We have explored this already in great detail internally.
from otto.
To answer the original question, you should unregister where appropriate for that object. As far as I can tell there's two cases:
- An object is responsible for managing something long lived. It registers once and stays hooked up to the bus until the process dies.
- An object is tied to something in the app that has a lifecycle (even if that lifecycle is not direct). An example from a comment is an adapter which is an object that is tied to a view. The view has a lifecycle of
onAttachedToWindow
andonDetachedFromWindow
. A view is sometimes managed by a fragment which hasonResume
andonPause
. All views are inside of activities which haveonResume
andonPause
. There are plenty of lifecycles here for you to latch on to.
There are hybrids of the first case (such as something tied to the user being logged in) but ultimately that's just an extra conditional.
If you can't fit your object into one of these two categories you should evaluate whether or not it's the right type to actually be on the bus.
The bus is solely a means of decoupling parts of your app. It's no different than the strong reference that a listener would impose.
from otto.
"just being lazy and not wanting to properly tie registration to a lifecycle or you are not in proper control of a lifecycle "
The same argument can be made for memory management or any object and is always a huge headache because humans do not track allocations as well as machines. Hence the purpose of a garbage collection system.
Java is fundamentally based on garbage collection and is "lazy" when it comes to memory management. Java developers have grown accustomed to expecting this sort of "lazy" behavior on many levels of an api. While introducing weak references can cause more issues, it can also fix a lot of problems too. Notably, imperfect human problems.
Weak referencing doesn't have to be the default but I for one would at least like to be able to control how my objects are registered and unregistered. Perhaps an abstract class or a subscriber storage interface?
from otto.
I don't why the discussion the Bus will secure and holde your object while is registered once you unsubscribe to it then the reference would be garbage collectable having Weak reference on the bus will defeat the purpose as it would not provide any certain that the object would still be around.
from otto.
Related Issues (20)
- duplicate entry: com/squareup/otto/AnnotatedHandlerFinder.class HOT 1
- NoClassDefFoundError when running in Android OS below 5.0. HOT 3
- subcriber received two same event HOT 2
- Please include the deprecated notice in the info website
- Examples HOT 1
- Please add notice to website about otto deprication HOT 1
- How to customize ThreadEnforcer HOT 4
- Using privitives in callback haven't invoked it. HOT 3
- Link for Migrating to RxJava is dead. HOT 1
- Private EventHandler makes it impossible to override Bus#dispatch HOT 1
- OnEvent not calling in navigationdrawer fragment
- otto with JavascriptInterface in api < 17 HOT 1
- Ship proguard rules in the aar? HOT 1
- A new call to post in a subscriber does not call its subscribers until the first call is completed HOT 1
- Reason for its name HOT 1
- android.database.sqlite.SQLiteException: no such table HOT 4
- Update for Gradle 4 and Bus doesnt work more. HOT 3
- I can't receive the event HOT 1
- java.lang.RuntimeException: Could not dispatch event: class abc to handler
- java.lang.RuntimeException: Could not dispatch event HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from otto.