Статьи

Связь в приложении для Android с EventBus

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

На нижнем уровне архитектуры вашего приложения, например, в базе данных, когда происходит какое-либо действие, вы можете отправить данные на более высокий уровень, такой как представление. Для этого вы можете создать интерфейс слушателя, асинхронные задачи или обратные вызовы. Все это будет работать, но у них есть некоторые существенные недостатки:

  1. прямая или жесткая связь
  2. индивидуальная регистрация и отмена регистрации нескольких зависимостей
  3. повторение кода
  4. сложность в тестировании
  5. повышенный риск ошибок

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

Чтобы использовать Greenrobot EventBus, вам необходимо сначала добавить его в файл build.gradle модуля приложения , включить compile 'org.greenrobot: eventbus :3.0.0' , а затем синхронизировать ваш проект.

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

1. Зарегистрируйте абонента в шине событий с помощью register() . Это сообщает шине событий, что вы хотите начать получать события. В onStart() это происходит в onStart() , а во фрагменте — в onAttact(Activity activity) .

1
2
3
4
5
@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

2. Отмените регистрацию подписчика, что означает, что шина событий перестает отправлять мне события. В onStop() это происходит в onStop() , а во фрагменте — в onDetach() .

1
2
3
4
5
@Override
public void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this);
}

3. onEvent() чтобы указать тип события, которое вы хотите получить, и действие, которое нужно предпринять при получении события. Обратите внимание на аннотацию @Subscribe в верхней части этого метода. В этом случае мы хотим подписаться на обычное событие, а не на липкое — я объясню разницу позже.

1
2
3
4
@Subscribe
public void onEvent(MessageEvent event) {
     Toast.makeText(this, «Hey, my message» + event.getMessage(), Toast.LENGTH_SHORT).show();.
}

События в greenrobot EventBus — это просто объекты, которые вы определяете. Вы можете иметь разные классы событий, если хотите. Они не наследуют какой-либо базовый класс или интерфейс — они просто POJO (простые старые объекты Java).

01
02
03
04
05
06
07
08
09
10
11
12
public class MessageEvent {
 
    public String mMessage;
 
    public MessageEvent(String message) {
        mMessage = message;
    }
 
    public String getMessage() {
        return mMessage;
    }
}

Основным отличием между событием после события и событием после прикрепления является механизм кэширования, используемый внутри шины событий. Когда кто-то публикует липкое событие, это событие сохраняется в кэше. Когда новое действие или фрагмент подписывается на шину событий, оно получает последнее событие sticky из кэша, вместо того, чтобы ждать его повторного запуска на шину событий, поэтому это событие остается в кэше даже после того, как подписчик его получил.

Важные события публикуются с помощью postSticky(MessageEvent) , а postSticky(MessageEvent) события — с помощью метода post(MessageEvent) .

1
2
EventBus.getDefault().postSticky(new MessageEvent(«Hey event subscriber!»));
EventBus.getDefault().post(new MessageEvent(«Hey event subscriber!»));

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

Итак, когда вы решите использовать событие post-sticky? Это можно сделать, если вы отслеживаете местоположение пользователя или просто кэшируете данные, отслеживаете уровень заряда батареи и т. Д.

1
EventBus.getDefault().postSticky(new LocationReceivedEvent(6.4531, 3.3958))
1
2
3
4
5
// UI updates must run on MainThread
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {
    textField.setText(event.getMessage());
}

Чтобы подписаться на липкое событие, вы включаете sticky = true внутри аннотации @Subscribe . Это указывает на то, что мы хотим получить залипшее событие типа MessageEvent из кэша.

1
2
3
4
LocationReceivedEvent locationReceivedStickyEvent = EventBus.getDefault().getStickyEvent(LocationReceived.class);
if(stickyEvent != null) {
    EventBus.getDefault().removeStickyEvent(locationReceivedStickyEvent);
}

removeStickyEvent(Event) удаляет removeStickyEvent(Event) событие из кэша, а removeAllStickyEvents() удаляет все залипшие события.

Подписчикам доступны четыре режима потока: публикация, основной, фоновый и асинхронный.

1
@Subscribe(threadMode = ThreadMode.POSTING)

Это по умолчанию. Подписчики будут вызываться в той же ветке, что и ветка, в которой публикуется событие. Включение ThreadMode.POSTING в аннотацию @Subscribe необязательно.

1
@Subscribe(threadMode = ThreadMode.MAIN)

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

1
@Subscribe(threadMode = ThreadMode.BACKGROUND)

В этом режиме потока подписчики будут получать события в том же потоке, в котором они опубликованы, как и в ThreadMode.POSTING . Разница в том, что если событие публикуется в главном потоке, подписчики получают его в фоновом потоке. Это гарантирует, что обработка событий не блокирует пользовательский интерфейс приложения. Тем не менее, не запускайте операцию, которая займет много времени в этом потоке.

1
@Subscribe(threadMode = ThreadMode.ASYNC)

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

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

1
2
3
4
@Subscribe(priority = 1);
public void onEvent(MessageEvent event) {
    textField.setText(event.getMessage());
}

Если вы хотите остановить доставку события другим подписчикам, вызовите метод cancelEventDelivery(Object event) внутри метода обработки события подписчика.

1
2
3
4
@Subscribe
public void onEvent(MessageEvent event){
    EventBus.getDefault().cancelEventDelivery(event);
}

В этом уроке вы узнали о:

  • зеленый робот EventBus и как он может улучшить ваше приложение для Android
  • разница между обычными и липкими событиями
  • различные режимы резьбы доступны и когда использовать каждый
  • приоритеты абонента
  • отмена события, чтобы прекратить получать события

Чтобы узнать больше о Greenrobot EventBus , я предлагаю вам посетить официальную документацию .

Другая библиотека, которую вы можете использовать для реализации шины событий, — это RxAndroid. Ознакомьтесь с нашей статьей о RxAndroid здесь на Envato Tuts + или попробуйте другие наши курсы или руководства по Android.

  • Начало работы с ReactiveX на Android

  • Введение в Loopj

  • Android с нуля: понимание трансляций Android

  • Анимируйте ваше приложение для Android