публикация события greenrobot EventBus в Android

Используя EventBus, мне нужно опубликовать событие (MyEvent) в действии и получить событие в другом действии в Android. Я попробовал проект тестирования производительности greenrobot EventBus, но не смог понять, как это сделать.

Я пытался в ActivitySubscriber

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

и попытался получить событие в ActivityReceiver как

EventBus.getDefault().register(this);

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

но я не могу получить событие. Может ли кто-нибудь дать мне знать, где я делаю неправильно?


person ronie    schedule 10.01.2013    source источник
comment
Можете ли вы немного почистить форматирование в своем вопросе?   -  person tacaswell    schedule 12.07.2013
comment
Возможно, вы захотите ознакомиться с этим руководством прямо сейчас: greenrobot.org/eventbus/documentation /конфигурация/   -  person IgorGanapolsky    schedule 13.11.2017


Ответы (4)


Поскольку это два действия, ActivitySubscriber публикует событие, пока ActivityReceiver еще не создано или находится в режиме ожидания (onStop()). Вам нужно использовать липкие события, т.е.

  • ActivitySubscriber.postSticky(...)

А для ActivityReceiver у вас есть два варианта:

  • EventBus.getDefault().register(this) и где-то после этого EventBus.getDefault().getStickyEvent()
  • EventBus.getDefault().registerSticky(), а затем с помощью обычного EventBus.getDefault().onEvent(...)

Обновлено: EventBus 3.0 меняет способ подписки.

Нет необходимости в именах методов, которые заканчиваются определенными суффиксами, а скорее в аннотациях.

Как использовать версию 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);
    }
}

Для получения более подробной информации и сравнения версии 3:

Некоторые детали извлечены из источников:

  • ThreadMode.PostThread
    #P8#
  • ThreadMode.MainThread
    #P9#
  • ThreadMode.BackgroundThread <блочная цитата> #P10#
  • ThreadMode.Async
    #P11#
  • default values for @Subscribe
    • threadMode = ThreadMode.PostThread
    • sticky = false — если true, доставляет самое последнее закрепленное событие (опубликованное с de.greenrobot.event.EventBus.postSticky(Object) этому подписчику (если событие доступно)
    • priority = 0 - приоритет подписчика влиять на порядок доставки событий. В рамках одного и того же потока доставки подписчики с более высоким приоритетом получат события раньше других с более низким приоритетом. Приоритет по умолчанию равен 0. Примечание: приоритет НЕ влияет на порядок доставки между подписчиками с разными режимами потока.

Редактировать 2

Теперь есть специальный сайт для любых вопросов по Greenrobot EventBus от создателя библиотеки:

http://greenrobot.org/eventbus/

person Dimitar Genov    schedule 04.02.2013
comment
почему он показывает, что registerSticky(Object, Class‹?›, Class‹?›...) из типа EventBus устарел? - person LOG_TAG; 12.09.2014
comment
Правильная реализация сейчас: @Subscribe(threadMode = ThreadMode.MainThread) public void onEventBusEvent(YourEvent event) { // 'onEventBusEvent' can be named as you'd like } - person Dimitar Genov; 23.06.2015
comment
какого черта... и почему документация не обновляется на сайте greenrobots? - person Erik Mueller; 20.11.2015
comment
В каком потоке я должен вызывать модифицированные сетевые службы, если я вызываю это из onEvent. - person PJ2104; 16.03.2018

  1. Добавлять

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

в раздел зависимостей модуля Modules Build gradle

  1. Создайте класс MessageEvent, например

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. Предположим, что у нас есть Fragment1 и есть кнопка, которая предполагает отправку сообщений в 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. Завершите, наконец, MainActivity, чтобы слушать и выполнять действия

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

person Kadir Erturk    schedule 25.11.2016

Внутри класса ActivityReceiver замените

EventBus.getDefault().register(this); 

с участием

EventBus.getDefault().register(this, MyEvent.class);
person user3124780    schedule 20.08.2014
comment
он показывает, что метод registerSticky(Object, Class‹?›, Class‹?›...) из типа EventBus устарел - person LOG_TAG; 12.09.2014

Это действительно зависит от того, когда и где этот код существует. Помните, что вы должны зарегистрироваться для получения событий, прежде чем сможете их получать, и регистрация происходит во время выполнения, а не во время компиляции.

Таким образом, вы должны убедиться, что публикуете событие после регистрации второго действия. Я бы просто поставил несколько точек останова на следующие строки и убедился, что отладчик останавливается здесь:

EventBus.getDefault().register(this); 

прежде чем вы доберетесь сюда:

EventBus.getDefault().post(event);
person shredder    schedule 26.02.2016