Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send event from Service to Activity with Otto event bus?

Tags:

android

otto

Simple BusProvider.getInstance().post() bring exception not main thread. How to send event from Service to Activity with Otto event bus?

like image 962
Mecid Avatar asked Mar 15 '13 11:03

Mecid


People also ask

How do you use the Otto bus?

To use Otto, create a singleton instance of the Bus class and provide access to it for your Android components. This is typically done in the Application object of your Android application. public static Bus bus = new Bus(ThreadEnforcer.

How does event bus work?

EventBus is an open-source library for Android and Java using the publisher/subscriber pattern for loose coupling. EventBus enables central communication to decoupled classes with just a few lines of code – simplifying the code, removing dependencies, and speeding up app development.

How do I use EventBus on Android?

To tell the EventBus to trigger this method we need to add the @Subscribe annotation to the method. We should unregister and re-register the EventBus in the onStart and onDestroy method on the activity. Now we will call this method on the add item click of second activity.

Why do we need event bus?

When are Eventbuses useful? Eventbuses are useful when you don't want components to depend on each other. Instead of a component having many references to other components, it can just send Events to an Eventbus and does not have to worry about who will take care of them.


2 Answers

To post from any thread (main or background) and receive on the main thread, try something like

public class MainThreadBus extends Bus {   private final Handler mHandler = new Handler(Looper.getMainLooper());    @Override   public void post(final Object event) {     if (Looper.myLooper() == Looper.getMainLooper()) {       super.post(event);     } else {       mHandler.post(new Runnable() {         @Override         public void run() {           MainThreadBus.super.post(event);         }       });     }   } } 

Note: credit goes to Jake Wharton and "pommedeterresaute" at https://github.com/square/otto/issues/38 for the general approach. I just implemented it with a wrapper class rather than a subclass.

like image 135
Andy Dennie Avatar answered Sep 19 '22 15:09

Andy Dennie


To post from any thread (main or background) and receive on the main thread, use the following MainThreadBus instead of a vanilla Bus

public class MainThreadBus extends Bus {      private final Handler handler = new Handler(Looper.getMainLooper());       @Override public void post(final Object event) {         if (Looper.myLooper() == Looper.getMainLooper()) {             super.post(event);         } else {             handler.post(new Runnable() {                 @Override                 public void run() {                     MainThreadBus.super.post(event);                 }             });         }     } } 

This is based on Andy Dennie's answer.

There is no need to both extend and wrap a Bus object, do one or the other. In Dennie's answer, which is effectively a wrapper, the Bus base class is just being used like an interface, all the functionality is overwritten.

It would work even if you removed the Bus base class unless you happened to reference the MainThreadBus via a Bus reference.

like image 42
alexbirkett Avatar answered Sep 19 '22 15:09

alexbirkett