Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event Bus Fragment Unregister

I've a splashscreen Fragment that is registered to event bus:

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

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

If the screen goes autolock (or any other event that could call onStop), the container activity goes onStop and the fragment is no more capable to receive the (network) event. I'm thinking about moving "unregister" logic to onDestroy method. Is it a good idea?

like image 418
Jumpa Avatar asked Jul 19 '15 09:07

Jumpa


2 Answers

You can move the event bus events to onStart() and onStop(), BUT you should know that certain methods cannot be called after onSaveInstanceState() (for example, dismissing a DialogFragment crashes you out).

So while this example was for Otto, I switched it to EventBus, and I personally have a wrapper that stores events while the application is paused.

public enum SingletonBus {
    INSTANCE;

    private static String TAG = SingletonBus.class.getSimpleName();

    private final Vector<Object> eventQueueBuffer = new Vector<>();

    private boolean paused;

    public <T> void post(final T event) {
            if (paused) {
                eventQueueBuffer.add(event);
            } else {
                EventBus.getDefault().post(event);
            }
    }

    public <T> void register(T subscriber) {
        EventBus.getDefault().register(subscriber);
    }

    public <T> void unregister(T subscriber) {
        EventBus.getDefault().unregister(subscriber);
    }

    public boolean isPaused() {
        return paused;
    }

    public void setPaused(boolean paused) {
        this.paused = paused;
        if (!paused) {
            Iterator<Object> eventIterator = eventQueueBuffer.iterator();
            while (eventIterator.hasNext()) {
                Object event = eventIterator.next();
                post(event);
                eventIterator.remove();
            }
        }
    }
}

Then in a BaseActivity of sorts,

public class BaseActivity extends AppCompatActivity {
     @Override
     public void onPostResume() {
          super.onPostResume();
          SingletonBus.INSTANCE.setPaused(false);
     }

     @Override
     public void onPause() {
          SingletonBus.INSTANCE.setPaused(true);
          super.onPause();
     }
}
like image 156
EpicPandaForce Avatar answered Nov 08 '22 13:11

EpicPandaForce


I recently had a similar issue. First I used Otto and then switched to greenrobot's EventBus. With EventBus you can register your objects sticky. EventBus.getDefault().registerSticky(this) That is, this object will automatically receive every sticky event it is waiting for after registration. These events then have to be posted sticky. (EventBus.getDefault().postSticky(event))

Consider to remove the sticky events if you don't need them anymore (EventBus.getDefault().removeSticky(Event.class)). So if you want to receive this event only once you should remove it. Maybe this approach might fit your needs.

like image 30
Chris Fox Avatar answered Nov 08 '22 11:11

Chris Fox