При использовании EventBus я столкнулся с неожиданной ситуацией, когда метод подписки фрагмента вызывается один раз даже после того, как фрагмент не зарегистрирован.
Сценарий такой. У меня есть действие, содержащее макет, в который можно поместить любой фрагмент. Активность начинается с определенного Фрагмента.
Активность и фрагмент регистрируются на своем onResume()
и отменяются на onPause()
. У них есть свои обработчики для каждого события одного типа.
По отправленному событию действие заменяет фрагмент другим по какому-либо условию. Затем во время процесса удаления вызывается onPause()
фрагмента, а также выполняется EventBus.getDefault().unregister(this)
.
Итак, я ожидаю, что обработчик фрагмента больше не будет вызываться. НО он вызывается один раз сразу после отмены регистрации Фрагмента.
Похоже, что EventBus не обрабатывает случай, когда какой-либо подписчик не зарегистрирован во время процесса публикации события. Кто-нибудь знает об этой проблеме?
Отредактировано для более подробной информации
Связанные методы во фрагменте
@Override public void onResume() { Log.d(LOG_TAG, "onResume()"); super.onResume(); EventBus.getDefault().register(this); Communicator.registerListener(listener); } @Override public void onPause() { Log.d(LOG_TAG, "onPause()"); Communicator.unregisterListener(listener); EventBus.getDefault().unregister(this); super.onPause(); } @Subscribe(sticky = true) public void handleEvent(DeviceConnectionSelectEvent event) { if (event.container != null) { setDevice(event.container.getRapaelDevice()); } }
Стек вызовов из
onPause()
Fragment.onPause() at com.neofect.rapael.client.bridge.app.device.kids.SmartKidsSensorDataFragment.onPause(SmartKidsSensorDataFragment.java:105) at android.support.v4.app.Fragment.performPause(Fragment.java:2139) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1117) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1234) at android.support.v4.app.FragmentManagerImpl.dispatchPause(FragmentManager.java:2060) at android.support.v4.app.Fragment.performPause(Fragment.java:2135) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1117) at android.support.v4.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1349) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:695) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570) at com.neofect.rapael.client.bridge.app.MainActivity.changeDeviceDetailFragment(MainActivity.java:111) at com.neofect.rapael.client.bridge.app.MainActivity.handleEvent(MainActivity.java:100) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at org.greenrobot.eventbus.EventBus.invokeSubscriber(EventBus.java:485) at org.greenrobot.eventbus.EventBus.postToSubscription(EventBus.java:416) at org.greenrobot.eventbus.EventBus.postSingleEventForEventType(EventBus.java:397) at org.greenrobot.eventbus.EventBus.postSingleEvent(EventBus.java:370) at org.greenrobot.eventbus.EventBus.post(EventBus.java:251) at org.greenrobot.eventbus.EventBus.postSticky(EventBus.java:292) at com.neofect.rapael.client.bridge.app.ui.device_connection_list.DeviceConnectionListPresenter.selectConnectionItem(DeviceConnectionListPresenter.java:114) at com.neofect.rapael.client.bridge.app.ui.device_connection_list.DeviceConnectionListPresenter.access$400(DeviceConnectionListPresenter.java:28) at com.neofect.rapael.client.bridge.app.ui.device_connection_list.DeviceConnectionListPresenter$1.onDeviceReady(DeviceConnectionListPresenter.java:179) at com.neofect.rapael.client.bridge.app.ui.device_connection_list.DeviceConnectionListPresenter$1.onDeviceReady(DeviceConnectionListPresenter.java:122) at com.neofect.communicator.CommunicationHandler$5.run(CommunicationHandler.java:90) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) at dalvik.system.NativeStart.main(Native Method)
Стек вызовов
handleEvent()
— вызывается сразу после вышеуказанногоonPause()
Fragment.handleEvent() at com.neofect.rapael.client.bridge.app.device.kids.SmartKidsSensorDataFragment.handleEvent(SmartKidsSensorDataFragment.java:121) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at org.greenrobot.eventbus.EventBus.invokeSubscriber(EventBus.java:485) at org.greenrobot.eventbus.EventBus.postToSubscription(EventBus.java:416) at org.greenrobot.eventbus.EventBus.postSingleEventForEventType(EventBus.java:397) at org.greenrobot.eventbus.EventBus.postSingleEvent(EventBus.java:370) at org.greenrobot.eventbus.EventBus.post(EventBus.java:251) at org.greenrobot.eventbus.EventBus.postSticky(EventBus.java:292) at com.neofect.rapael.client.bridge.app.ui.device_connection_list.DeviceConnectionListPresenter.selectConnectionItem(DeviceConnectionListPresenter.java:114) at com.neofect.rapael.client.bridge.app.ui.device_connection_list.DeviceConnectionListPresenter.access$400(DeviceConnectionListPresenter.java:28) at com.neofect.rapael.client.bridge.app.ui.device_connection_list.DeviceConnectionListPresenter$1.onDeviceReady(DeviceConnectionListPresenter.java:179) at com.neofect.rapael.client.bridge.app.ui.device_connection_list.DeviceConnectionListPresenter$1.onDeviceReady(DeviceConnectionListPresenter.java:122) at com.neofect.communicator.CommunicationHandler$5.run(CommunicationHandler.java:90) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5017) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) at dalvik.system.NativeStart.main(Native Method)
handleEvent()
вызывается в том же стеке вызовов, что и onPause()
, согласно приведенному выше. Они называются в одной проводке события.
Я предполагаю, что цикл диспетчеризации событий (цикл очереди сообщений) сохраняет список подписок ДО начала публикации, поэтому он не может обработать удаление подписки, выполненное во время процесса публикации.
unregister()
до или послеsuper.onPause()
? - person SqueezyMo   schedule 24.05.2016