greenrobot EventBus post event in Android

橙三吉。 提交于 2019-12-03 13:36:51

问题


By using EventBus, I need to post an event(MyEvent) in an Activity and receive the event in another Activity in Android. I tried the greenrobot EventBus performance test project but could not get how to do it.

I tried in ActivitySubscriber

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

and tried to receive the event in ActivityReceiver as

EventBus.getDefault().register(this);

public void onEvent(MyEvent event){
....
}

but I am unable to receive the event. Can anyone let me know where am I doing wrong?


回答1:


Since they are two activities, ActivitySubscriber posts the event while ActivityReceiver is still not created, or is in stall 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 to subscribe.

There is no need of method names which end up 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, i.e. 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);
    }
}

For more details and comparison of version 3:

  • http://androiddevblog.com/eventbus-3-droidcon/
  • http://androiddevblog.com/wordpress/wp-content/uploads/EventBus3.pdf

Some details extracted from the sources:

  • ThreadMode.PostThread

    Subscriber will be called in the same thread, which is posting the event. This is the default. Event delivery implies the least overhead because it avoids 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 must return quickly to avoid blocking the posting thread, which may be the main thread.

  • ThreadMode.MainThread

    Subscriber will be called in Android's main thread (sometimes referred to as UI thread). If the posting thread is the main thread, event handler methods will be called directly. Event handlers using this mode must return quickly to avoid blocking the main thread.

  • ThreadMode.BackgroundThread

    Subscriber will be called in a background thread. If posting thread is not the main thread, event handler methods will be called directly in the posting thread. If the posting thread is 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.

  • ThreadMode.Async

    Event handler methods are called in a separate thread. This is always independent from the posting thread and the main thread. 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, e.g. for network access. Avoid triggering a large number of long running asynchronous handler methods at the same time to limit the number of concurrent 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 (posted with de.greenrobot.event.EventBus.postSticky(Object) to this subscriber (if event available)
    • priority = 0 - Subscriber priority to influence the order of event delivery. Within the same delivery thread, higher priority subscribers will receive events before others with a lower priority. The default priority is 0. Note: the priority does NOT affect the order of delivery among subscribers with different thread modes.

Edit 2

There is a dedicated site now for any Greenrobot EventBus questions from the creator of the lib:

http://greenrobot.org/eventbus/




回答2:


  1. Add

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

into dependencies section of Modules Build gradle

  1. Create a MessageEvent class like

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. Assume that we have Fragment1 and there is a button that suppose 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 to listen and do action

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();
    }
}



回答3:


Inside ActivityReceiver class, replace

EventBus.getDefault().register(this); 

with

EventBus.getDefault().register(this, MyEvent.class);



回答4:


It really depends when and where this code exists. Remember that you must register for the events before you can receive them, and registering takes place at runtime, not compile time.

So, you must ensure that you are posting the event after you have registered the second activity. I would simply put some breakpoints on the following lines and ensure that the debugger stops here:

EventBus.getDefault().register(this); 

before you get to here:

EventBus.getDefault().post(event);


来源:https://stackoverflow.com/questions/14263183/greenrobot-eventbus-post-event-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!