Типичное приложение для Android, как правило, состоит из множества слоев, модулей или структур, таких как фрагменты, действия, докладчики и службы. Эффективная связь между этими компонентами может стать затруднительной, если они тесно связаны друг с другом.
На нижнем уровне архитектуры вашего приложения, например, в базе данных, когда происходит какое-либо действие, вы можете отправить данные на более высокий уровень, такой как представление. Для этого вы можете создать интерфейс слушателя, асинхронные задачи или обратные вызовы. Все это будет работать, но у них есть некоторые существенные недостатки:
- прямая или жесткая связь
- индивидуальная регистрация и отмена регистрации нескольких зависимостей
- повторение кода
- сложность в тестировании
- повышенный риск ошибок
Использование архитектуры публикации / подписки или шины сообщений предотвращает все потенциальные проблемы, выделенные выше. Это очень хороший способ реализовать эффективную связь между компонентами в приложении без необходимости немедленного уведомления других. Используя функцию публикации / подписки в 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;
}
}
|
Post Event и Post Sticky Event
Основным отличием между событием после события и событием после прикрепления является механизм кэширования, используемый внутри шины событий. Когда кто-то публикует липкое событие, это событие сохраняется в кэше. Когда новое действие или фрагмент подписывается на шину событий, оно получает последнее событие 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))
|
Подписаться на сообщение Sticky Event
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
из кэша.
Удаление Sticky Events
1
2
3
4
|
LocationReceivedEvent locationReceivedStickyEvent = EventBus.getDefault().getStickyEvent(LocationReceived.class);
if(stickyEvent != null) {
EventBus.getDefault().removeStickyEvent(locationReceivedStickyEvent);
}
|
removeStickyEvent(Event)
удаляет removeStickyEvent(Event)
событие из кэша, а removeAllStickyEvents()
удаляет все залипшие события.
EventBus Thread Modes
Подписчикам доступны четыре режима потока: публикация, основной, фоновый и асинхронный.
оприходование
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.