EventBus in Android [Part 1]

What is Eventbus?

EventBus is a publish/subscribe event bus for Android and Java.

eventbus android

Why EventBus?

  • simplifies the communication between components.
  • decouples event senders and receivers.
  • performs well with Activities, Fragments, and background threads.
  • avoids complex and error-prone dependencies and life cycle issues.
  • makes your code simpler is fast is tiny (~50k jar).
  • has advanced features like delivery threads, subscriber priorities, etc.

Add EventBus to your project

dependencies{
compile 'org.greenrobot:eventbus:3.1.1'
}

Retrofit Android Example With Recyclerview

Android Recyclerview Material Design


get started with EventBus

Step 1: Define events

Events are POJO (plain old Java object) without any specific requirements.

public class User {

   private String name;

   private String address;

   public User(String name, String address) {
       this.name = name;
       this.address = address;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

}

Step 2: Prepare subscribers

  • Implement the subscriber method to get notified when the event is posted.
  • The subscriber method should be annotated with @subscibe.
@Subscribe(threadMode = ThreadMode.MAIN)
public void onUserUpdate(User user){
   Log.d("user",user.toString());
//Your own operation here
}

Note,

Subscribers also need to register and unregister from the bus according to there life cycle. Then Only subscribers can able to receive events. In Android, in activities and fragments, you should usually register.

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

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

Swipe card view Android with Example[Updated]

Expandable Recyclerview For Android


Step 3: Post events

Post an event from any part of your code. All currently registered subscribers matching the event type will receive it.

User user = new User("Velmurugan","India");
EventBus.getDefault().post(user);

ThreadMode

EventBus can handle threading for you, the events threads can be different from the posting thread. A common use case is dealing with UI changes. In Android, UI changes must be done in the UI (main) thread. On the other hand, networking, or any time-consuming task, must not run on the main thread. EventBus helps you to deal with those tasks and synchronize with the UI thread.

In EventBus, you may define the thread that will call the event handling method by using one of the following ThreadModes.

ThreadMode: POSTING

  • Subscribers will be called in the same thread posting the event. This is the default.
  • Event delivery is done synchronously.
  • This ThreadMode avoids the thread switching completely.
  • Thus this is the recommended mode for simple tasks that are known to complete is a very short time without requiring the main thread.
  • Event handlers using this mode should return quickly to avoid blocking the posting thread, which may be the main thread.
@Subscribe(threadMode = ThreadMode.POSTING)
public void onUserUpdate(User user){
   Log.d("user",user.toString());
}

ThreadMode: MAIN

  • Subscribers will be called in Android’s main thread ( UI thread).
  • Event delivery is done synchronously.
  • thread switching is there if the posting the in background thread.
  • Event handlers using this mode must return quickly to avoid blocking the main.
@Subscribe(threadMode = ThreadMode.MAIN)
public void onUserUpdate(User user){
   Log.d("user",user.toString());
}

ThreadMode: MAIN_ORDERED

  • Subscribers will be called in Android’s main thread.  ( UI thread).
  • The event is always enqueued for later delivery to subscribers, so the call to post will return immediately. This gives event processing a stricter and more consistent order (thus the name MAIN_ORDERED). For example, if you post another event in an event handler with MAIN thread mode, the second event handler will finish before the first one (because it is called synchronously – compare it to a method call). With MAIN_ORDERED, the first event handler will finish, and then the second one will be invoked at a later point in time (as soon as the main thread has capacity).
  • thread switching is there if the posting the in background thread.
  • Event handlers using this mode must return quickly to avoid blocking the main.
@Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onUserUpdate(User user){
   Log.d("user",user.toString());
}

ThreadMode: BACKGROUND

  • Subscribers will be called in a background thread.
  • Event delivery is done synchronously.
  • If posting a thread in the main thread, EventBus uses a single background thread that will deliver all its events sequentially.
  • Event handlers using this mode should try to return quickly to avoid blocking the background thread.
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onUserUpdate(User user){
   Log.d("user",user.toString());
}

ThreadMode: ASYNC

  • Event handler methods are called in a separate thread.
  • This is always independent from the posting thread and the main thread.
  • EventBus uses a thread pool to efficiently reuse threads from completed asynchronous event handler notifications.
  • Posting events never wait for event handler methods using this mode. Event handler methods should use this mode if their execution might take some time.
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onUserUpdate(User user){
   Log.d("user",user.toString());
}

Example Program

BackgroundService.java

public class BackgroundService extends Service {

    public static final int notify = 5000;
    private Handler mHandler = new Handler();
    private Timer mTimer = null;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        EventBus.getDefault().register(this);
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        if (mTimer != null)
            mTimer.cancel();
        else
            mTimer = new Timer();

        mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify);
    }

    class TimeDisplay extends TimerTask {
        @Override
        public void run() {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    EventBus.getDefault().post(new Date());
                }
            });
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mTimer.cancel();
        EventBus.getDefault().unregister(this);
    }
}

User.java

public class User {

    private String name;

    private String address;

    public User(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private TextView tvDate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvDate = findViewById(R.id.tv_date);
        startService(new Intent(this, BackgroundService.class));
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onUpdateDate(Date date){
        Log.d("date = ",date.toString());
        tvDate.setText(date.toString());
    }

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

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

}
github_link

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top
%d bloggers like this: