Greenrobot Android EventBus Event

Using EventBus, I need to send an event (MyEvent) to an Activity and get the event in another Activity on Android. I tried the greenrobot EventBus performance testing project, but couldn't figure out how to do this.

I tried in ActivitySubscriber

MyEvent event = new MyEvent(); EventBus.getDefault().post(event); 

and tried to get the event in ActivityReceiver as

 EventBus.getDefault().register(this); public void onEvent(MyEvent event){ .... } 

but I can not accept this event. Can someone tell me where I am doing wrong?

+4
source share
4 answers

Since they are two actions, the ActivitySubscriber publishes the event, and the ActivityReceiver is still not created or is in standby mode ( onStop() ). You need to use sticky events i.e.

  • ActivitySubscriber.postSticky(...)

And for ActivityReceiver you have two options:

  • EventBus.getDefault().register(this) and somewhere after that EventBus.getDefault().getStickyEvent()
  • EventBus.getDefault().registerSticky() and then using regular EventBus.getDefault().onEvent(...)

Updated: EventBus 3.0 changes the way you subscribe.

There is no need for method names that end with specific suffixes, but rather annotations.

How to use version 3:

 //// in your build.gradle compile 'de.greenrobot:eventbus:3.0.0-beta1' // alternatively you can target latest whatever currently // compile 'de.greenrobot:eventbus:+' //// from a class which needs to dispatch an event // posting an event is as before, no changes // here we dispatch a sticky event EventBus.getDefault().postSticky(myStickyEvent); //// from your class which needs to listen // method name can be any name // any of subscribe params is optional, ie can use just @Subscribe @Subscribe(threadMode = ThreadMode.MainThread, sticky = true, priority = 1) public void onEventBusEvent(@Nullable final StickyEvent stickyEvent) { if (stickyEvent != null) { ... // optionally you can clean your sticky event in different ways EventBus.getDefault().removeAllStickyEvents(); // EventBus.getDefault().removeStickyEvent(stickyEvent); // EventBus.getDefault().removeStickyEvent(StickyEvent.class); } } 

More details and comparison of version 3:

Some details are extracted from sources:

  • ThreadMode.PostThread

    The subscriber will be called in the same thread that sends the event. This is the default value. Event delivery is the least expensive since it completely eliminates thread switching. Thus, this is the recommended mode for simple tasks that are known to be completed, very short, without requiring a main thread. Event handlers using this mode should return quickly so as not to block the wiring flow, which may be the main thread.

  • ThreadMode.MainThread

    The caller will be called in the main Android theme (sometimes called the user interface thread). If the posting thread is the main thread, the event handler methods will be called directly. Event handlers using this mode should return quickly to avoid blocking the main thread.

  • ThreadMode.BackgroundThread

    The subscriber will be called in the background thread. If the publication stream is not the main stream, the event handler methods will be called directly in the posting stream. If the posting thread is the main thread, EventBus uses a single background thread that will transmit all its events sequentially. Event handlers using this mode should try to quickly return to avoid blocking the background thread.

  • ThreadMode.Async

    Event handler methods are called in a separate thread. It always depends on the wiring flow and main flow. Posting events never wait for event handler methods using this mode. Event handler methods should use this mode if they can take some time to execute, for example. to access the network. Avoid running a large number of long asynchronous handler methods at the same time to limit the number of simultaneous threads. EventBus uses a thread pool to efficiently reuse threads from completed asynchronous event handler notifications.

  • default values for @Subscribe
    • threadMode = ThreadMode.PostThread
    • sticky = false - If true, delivers the most recent sticky event (dispatched using de.greenrobot.event.EventBus.postSticky(Object) this subscriber (if an event is available)
    • priority = 0 - subscriber priority affects the order in which events are delivered. Within the same delivery line, subscribers with a higher priority will receive events before others with a lower priority. The default priority is 0. Note: priority does NOT affect the delivery order among subscribers with different flow modes.

Edit 2

Now you have a dedicated site for any GreenBot EventBus questions from the creator of lib:

http://greenrobot.org/eventbus/

+22
source
  • Add

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

in the dependency section of the Build gradle Modules

  1. Create a MessageEvent class, for example

 public final class MessageEvent { private MessageEvent() { throw new UnsupportedOperationException("This class is non-instantiable"); } public static class Message1{ public String str1; public Message1(String str) { str1 = str; } } public static class Message2{ public String str2; public Message2(final String str) { str2 = str; } } } // so on 
  1. Suppose we have Fragment1, and there is a button that expects to send messages to MainActivity

 public class Fragment1 extends Fragment { private View frView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { frView = inflater.inflate(R.layout.fragment1, container, false); btn = (Button) frView.findViewById(R.id.button); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { frView.setBackgroundColor(Color.RED); EventBus.getDefault().post(new MessageEvent.Message1("1st message")); EventBus.getDefault().post(new MessageEvent.Message2("2nd message")); } }); return frView; } 
  1. End finally MainActivity for listening and performing actions

 public class MainActivity extends AppCompatActivity { @Override protected void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override protected void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fragment1 Fragment1 = new Fragment1(); getFragmentManager().beginTransaction().replace( R.id.activity_main, Fragment1, "Fragment 1").commit(); } @Subscribe(threadMode = ThreadMode.MAIN) public void onMessage1(MessageEvent.Message1 event) { Toast.makeText(getApplication(), event.str1, Toast.LENGTH_LONG).show(); } @Subscribe(threadMode = ThreadMode.MAIN) public void onMessage2(MessageEvent.Message2 event) { Toast.makeText(getApplication(), event.str2, Toast.LENGTH_LONG).show(); } } 
+2
source

Inside the ActivityReceiver class, replace

 EventBus.getDefault().register(this); 

with

 EventBus.getDefault().register(this, MyEvent.class); 
+1
source

It really depends on when and where this code exists. Remember that you must register for events before you can receive them, and registration is performed at run time, not compile time.

So, you must make sure that you post the event after registering the second action. I would just put some breakpoints on the following lines and ensure that the debugger stops here:

 EventBus.getDefault().register(this); 

before you go here:

 EventBus.getDefault().post(event); 
0
source

Source: https://habr.com/ru/post/1243020/


All Articles