Ошибка GreenRobot EventBus в фрагментах: подписчиков, зарегистрированных для класса событий
У меня есть действие, его макет содержит FrameLayout. Я использую framelayout как контейнер фрагмента. Я заменяю фрагменты в FrameLayout, используя транзакции FragmentManager.
В одном из методов onCreate фрагмента я регистрирую фрагмент с использованием EventBus.
@Override
public void onCreate(){
EventBus.getDefault().register(this);
// other initialization code
}
Фрагмент имеет GridView в своем макете. Всякий раз, когда щелкнут элемент в gridView, я отправляю событие в EventBus
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment_category, container, false);
gridView = (GridView) rootView.findViewById(R.id.categry_grid_view);
gridAdapter = new CustomGridAdapter(getActivity());
gridView.setAdapter(gridAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Category clickedCategory = gridAdapter.getItem(position);
EventBus.getDefault().post(new MyEvent());
}
});
Методы обработчика событий для этого события находятся в одном и том же фрагменте, то есть фрагмент имеет следующий метод
public void onEvent(MyEvent e){
//some code;
}
Это отлично работает, пока приложение не теряет фокус и становится неактивным (из-за нажатия домашней кнопки или блокировки экрана). Когда я снова активирую приложение, обработчики событий для событий не вызывают. Я могу видеть следующие утверждения в LogCat
com.example.app D/Event﹕ No subscribers registered for event class com.example.app.MyEvent
com.example.app D/Event﹕ No subscribers registered for event class de.greenrobot.event.NoSubscriberEvent
Может кто-нибудь сказать мне, что я делаю неправильно здесь?
Изменить 1:
Когда приложение становится неактивным из-за блокировки экрана или нажатой кнопки дома, вызывается метод onStop фрагмента. Код для отмены регистрации фрагмента из EventBus находится в методе onStop. Когда приложение снова активируется, вызывается метод onStart и onResume. Поэтому я переместил свой код, чтобы зарегистрировать фрагмент с EventBus в его методе onStart.
@Override
public void onStart(){
super.onStart();
EventBus.getDefault().register(this);
}
Я поместил несколько операторов журнала, чтобы проверить, действительно ли метод onStart вызывается, когда приложение становится активным. Он называется. Все еще не работает, когда приложение становится неактивным, а затем снова активным.
Изменить 2
Я забыл упомянуть, что активность, которая содержит этот фрагмент, также подписывается на EventBus. Код для регистрации активности с EventBus находится в методе onCreate, а код для отмены регистрации активности - в методе onStop.
Ответы
Ответ 1
Активность, которая содержала этот фрагмент, также подписалась на EventBus. Код для регистрации активности с EventBus был в методе onCreate, а код для отмены регистрации был в методе onStop.
Когда приложение стало неактивным (из-за блокировки экрана или нажатия кнопки "Главная" ), вызывающий метод onStop активности вызывался, и он получал unregisterd из EventBus. По какой-то причине его содержащие фрагменты также были незарегистрированы (я не уверен, почему). Повторная регистрация фрагментов с помощью EventBus не сработала.
Я решил эту проблему, переместив код, чтобы отменить регистрационную активность до его метода onDestroy.
Я все еще не уверен, почему это работает, но по крайней мере это решает мою текущую проблему. Если у кого-то есть объяснение или лучшее понимание, прокомментируйте или отправьте ответ.
Ответ 2
Для меня проблема была чем-то другим, я попытался сделать сообщение для фрагмента, который еще не был зафиксирован. Вы получите те же 2 ошибки, что и в вопросе.
Итак, я сделал getSupportFragmentManager().executePendingTransactions();
, прежде чем называть сообщение, и это устранило проблему для меня.