24

What is the best place to register and unregister to an event bus (like otto, EventBus, or tinybus) in an Activity and why?

  1. onCreate()-onDestroy()
  2. onStart()-onStop()
  3. onResume()-onPause()

Otto's example uses onResume()-onPause(), EventBus's mentions onStart()-onStop(), and we needed to use onCreate()-onDestroy() in our app to update the activity's UI even when it was in the background. So I guess it can be any of the three depending on the nature of the events and their handling, but I was wondering if there is anything more to it that should be considered.

levavare
  • 494
  • 1
  • 4
  • 13
  • 1
    I need to use `onCreate() - onDestroy()` as well. Did you find any drawbacks? – aandis Sep 04 '15 at 12:30
  • 1
    @zack, no I didn't find any drawbacks at the time, but it was only a PoC app, so it wasn't an extensive experience – levavare Oct 21 '15 at 17:13
  • @levavare, Please mark one of the answers below as accepted. It sounds like you've decided to agree with Jordy's answer/link but that doesn't have the most upvotes so it is harder to find. – Anne Gunn Jun 02 '16 at 10:56
  • @agunn I don't see an answer yet that would list the considerations, pros, cons for each one. onResume()-onPause() can cause missed events with dialogs, so it's probably best not to use, but as I see it deciding between onStart()-onResume() and onCreate()-onDestroy() depends on whether we want to handle event while app is in background. (eg: we might want to update UI (even if not shown at that moment), but not start a new activity) – levavare Jun 03 '16 at 16:30
  • @levavare, I agree with your 'it depends' observation. Please see my answer + example cases below. – Anne Gunn Jun 06 '16 at 13:40

4 Answers4

13

First of all, its not a objective question rather its a subjective one and will draw lots of arguments based on arguments.

From my experience, We used Otto in one of our project. We followed onResume()-onPause() which served us very good. It also makes sense cause we should register as late as possible & deregister as fast as possible while using an event bus.

Amit K. Saha
  • 5,871
  • 2
  • 27
  • 35
  • "as late as possible & deregister as fast as possible" - thanks, good point, makes some sense from the performance point of view of the event distribution too, I suppose, although not sure how much it actually matters. But I think starting from onResume-onPause and moving 'up' if needed makes sense. – levavare Mar 25 '15 at 09:06
  • yes. moving up according to scenario is the best tactics I think. Would you please accept the answer, if it serves your purpose? – Amit K. Saha Mar 25 '15 at 09:21
  • 18
    what about losing the dispatched events while app was in background? – gyosida Sep 28 '15 at 20:19
  • @Gianfranco Android's design is to discard Activity when in background... you see problems when app developers don't deal with this in various situations where you rotate the screen/etc. Especially on 512MB of 1MB devices, expect Activity to disappear. If you need an app to respond to events all the time - build a service that runs all the time and feeds data to the Activity. You can go one step further and become a foreground service with a notification. You will see this type of design in music player apps. – RoundSparrow hilltx Jan 19 '17 at 16:13
8

@levavare, I think the correct time to register/unregister depends on your events and what you intend to do with them. And can be different for different events within the same application.

For example, I'm using EventBus in an Android app that monitors a realtime data logging device (Arduino, in this case) via Bluetooth. I have two quite different types of events.

The first event is posted by my Bluetooth code to notify one of my fragments that a new set of instrument readings has been received from the device. That fragment then writes them to a database table. It's important that event always be heard and acted on. The fragment registers/unregisters in its OnCreate/OnDestroy methods. I also subscribe for that event with elevated priority.

The other event is posted by the database layer when the new record is added to the database. I have a series of fragments that show different subsets of the readings (temperatures, pressures, alarm conditions). When one of those fragments is being viewed it should update as soon as the new reading is in the database. But when the fragment is out of sight, there's no reason for it to act on a reading. I have those fragments register/unregister in OnStart/OnStop. I was going to do that work in OnResume/OnPause and, frankly, I think it would work as well there for my app. But @Jordy's answer and link convinced me to go with OnStart/OnStop instead.

Anne Gunn
  • 2,347
  • 1
  • 28
  • 42
3

I removed my comment in the above answer that it would be best to register / unregister in onresume/onpause. I got a strange usecase where some if my events werent reaching the annotated subscriber. Seems the best way is to use the onstart / onstop. Here is a good SO post explaining why:

https://stackoverflow.com/a/19737191/2361947

Community
  • 1
  • 1
Jordy
  • 1,764
  • 1
  • 22
  • 32
  • Thanks! I added and update on it in the question. The answer is still not obvious I think, if there will be any definite answer, I will update again. It looks like for me that using message buses solves some of our problems and can generate some others.. – levavare Apr 22 '15 at 14:53
  • Yup onStart/onStop is better as it can receive messages when the phone is locked. OR say a GCM message received can be passed to the activity via Otto – Pranaysharma Jan 18 '16 at 11:36
0

Form EventBus Documentation that I found and it's works fine for me:

@Override
 public void onStart() {
     super.onStart();
     EventBus.getDefault().register(this);
 }

 @Override
 public void onStop() {
     super.onStop();
     EventBus.getDefault().unregister(this);
 }

And if you need to send the EventBus reference to the child then:

private EventBus eventBus = EventBus.getDefault();
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        .......
}

@Override
public void onStart() {
    super.onStart();
    if(!eventBus.isRegistered(this)){
        eventBus.register(this);
    }else{
        Log.e(TAG, "EventBus is registered");
    }
}

@Override
public void onStop() {
    super.onStop();
    if(eventBus.isRegistered(this)){
       eventBus.unregister(this);
    }else{
       Log.e(TAG, "EventBus is not registered");
    }
}
Md Imran Choudhury
  • 9,343
  • 4
  • 62
  • 60