Гарантирован ли порядок прикрепленных событий Greenrobot EventBus?

Я начинаю использовать EventBus 3.0.0.

У меня 3 прикрепленных события, которые нужно отправить из Сервиса в Активность:

  1. действие началось
  2. прогресс действия
  3. действие закончено

я слушаю события в главном потоке:

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void on...Event(... event) {
...
}

Сервис отправляет события в порядке: started-progressN-..-progressM-finished и подписанная активность обновляет пользовательский интерфейс в соответствии с событиями.

После того, как действие повернуто, я ожидаю получить залипшие события в том порядке, в котором они были отправлены, иначе это нарушит пользовательский интерфейс (так как при запуске устанавливает прогресс в 0). Гарантирован ли порядок событий EventBus (при условии, что я использую один и тот же EventBus, один и тот же поток получателя, один и тот же подписчик для всех этих событий)?

Согласно моим тестам, это не гарантировано, и это особенность / проблема, не так ли?

до вращения:

07-27 11:27:55.254  27910-27910/ app D/App﹕ status Compilation started ...
07-27 11:27:55.254  27910-27910/ app D/App﹕ compile progress 0%
07-27 11:27:55.354  27910-27910/ app D/App﹕ compile progress 20%
07-27 11:27:55.354  27910-27910/ app D/App﹕ compile progress 30%
07-27 11:27:55.354  27910-27910/ app D/App﹕ compile progress 40%
07-27 11:27:55.844  27910-27910/ app D/App﹕ compile progress 50%

после поворота (повторяющиеся липкие события):

07-27 11:27:59.554  27910-27910/ app D/App﹕ compile progress 50%
07-27 11:27:59.554  27910-27910/ app D/App﹕ status Compilation started ...

1 ответ

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

Предполагая, что у вас есть 3 класса событий, таких как CompilationStart, CompilationProgress и CompilationFinish, вы можете указать приоритет 3, 2 и 1 соответственно, как показано ниже. В любом случае, помните, что приоритет по умолчанию равен 0, поэтому любое другое событие будет получено раньше всех этих:

@Subscribe(priority = 3);
public void onEvent(CompilationStart event) {
    ...
}
@Subscribe(priority = 2);
public void onEvent(CompilationProgress event) {
    ...
}
@Subscribe(priority = 1);
public void onEvent(CompilationFinish event) {
    ...
}

С другой стороны, вы можете избежать использования приоритета, если просто используете один класс, такой как CompilationInfo, который выглядит следующим образом:

public class CompilationInfo {
    public CompilationState compilationState;
    public int priority

    public CompilationInfo(CompilationState compilationState, int priority) {
        this.compilationState = compilationState;
        this.priority = priority;
    }
}

Где CompilationState - это родительский класс, из которого созданы методы CompilationStart, CompilationProgress и CompilationFinish. Было бы еще лучше, если бы вы использовали перечисление для поля приоритета, так как оно более читабельно. Таким образом, вам нужен только один метод onEvent.

РЕДАКТИРОВАТЬ: Изменены значения приоритетов в соответствии с изменениями документации

Другие вопросы по тегам