Otto (Bus de eventos), enviar fragmento de evento a fragmento pero no recibir

MainActivity tiene un NavigationDrawer y cada menú de navegación trae Fragment en lugar de nueva Activity.

Hay un fragmento de los ajustes y si cambio el orden del menú de la navegación debe ser reflejado inmediatamente a NavigationDrawerFragment.

Publicar evento en SettingsFragment, sin embargo, no aparece en NavigationDrawerFragment.

Hice un AndroidBus extiende Bus

public class AndroidBus extends Bus { private final Handler mainThread = new Handler(Looper.getMainLooper()); public AndroidBus() { super(ThreadEnforcer.ANY); } @Override public void post(final Object event) { if (BuildConfig.DEBUG) Ln.d("BUS: SYNC current thread="+Thread.currentThread().getName()+", post=" + event + " bus=" + this); if (Looper.myLooper() == Looper.getMainLooper()) { super.post(event); } else { mainThread.post(new Runnable() { @Override public void run() { post(event); } }); } } @Override public void register(Object object) { super.register(object); if (BuildConfig.DEBUG) Ln.d("BUS: SYNC current thread="+Thread.currentThread().getName()+", register=" + object + " bus=" + this); } @Override public void unregister(Object object) { super.unregister(object); if (BuildConfig.DEBUG) Ln.d("BUS: SYNC current thread="+Thread.currentThread().getName()+", unregister=" + object + " bus=" + this); } } 

y me inyecto objeto de bus a cada fragmento de Dagger y registro fragmento en onActivityCreated, y anular su registro onDestroyView.

Si publico el evento no se entrega y veo el registro de DeadEvent.

 08-07 11:00:27.203 3519-3519/com.test.app.debug D//AndroidBus.java:40﹕ main BUS: SYNC current thread=main, register=com.test.app.ui.MainActivity@536fa3b0 bus=[Bus "default"] 08-07 11:00:27.231 3519-3519/com.test.app.debug D//AndroidBus.java:40﹕ main BUS: SYNC current thread=main, register=NavigationDrawerFragment{536b79a4 #0 id=0x7f0a0072} bus=[Bus "default"] 08-07 11:00:27.247 3519-3519/com.test.app.debug D//MainActivity.java:127﹕ main SYNC: register: bus=[Bus "default"] 08-07 11:00:27.251 3519-3519/com.test.app.debug D//AndroidBus.java:40﹕ main BUS: SYNC current thread=main, register=SettingsFragment{536b7a2c #1 id=0x7f0a0071} bus=[Bus "default"] 08-07 11:00:31.415 3519-3519/com.test.app.debug D//AndroidBus.java:24﹕ main BUS: SYNC current thread=main, post=com.test.app.events.SettingsUpdatedEvent@536d1aa4 bus=[Bus "default"] 08-07 11:00:31.415 3519-3519/com.test.app.debug D//AndroidBus.java:24﹕ main BUS: SYNC current thread=main, post=com.squareup.otto.DeadEvent@5352027c bus=[Bus "default"] 

Registro MainActivity también en el método onCreate, si suscribo el mismo evento en MainActivity que recibe el evento.

Gracias por leer esto y espero que alguien me ilumine sobre esto.

Volví a este problema y encontré mi estupidez. La razón es que he usado diferentes anotaciones @Subscribe . Podría ocurrir cuando usas bibliotecas de Otto y Guava . Por lo tanto, ten cuidado con esto cuando uses ambas bibliotecas en tu aplicación de Android.

 -import com.google.common.eventbus.Subscribe; +import com.squareup.otto.Subscribe; 

AFAIK, su segundo fragmento no recibe mensaje de evento porque se crea demasiado tarde, mientras que el primer fragmento post evento antes del segundo fragmento onActivityCreated se llama.
Para solucionar esto, debe mantener el objeto de evento en la memoria hasta que se cree el segundo fragmento y pueda recibir este evento. No estoy seguro de que Otto Bus pueda soportar esta función. La segunda opción es mantener su objeto de evento en la clase de actividad y el segundo fragmento obtenerlo por llamada getActivity() , pero de esta manera se romperá el significado de EventBus .
Por lo tanto, recomiendo el último: utilizando GreenRobot EventBus , que soporta más funciones de Otto , por ejemplo: post en el hilo principal y el hilo de fondo, los eventos de caché (evento pegajoso). Su problema se realizará mediante el uso del evento Sticky con GreenRobot EventBus :

  // Register stictky subscribers on onResume() EventBus.getDefault().registerSticky(this); // Unregister subscriber on onPause() EventBus.getDefault().unregister(this); // your subscribe event here public void onEvent(AnyEventType event) { } // or subscribe event on main thread public void onEventMainThread(AnyEventType event) { } // Post sticky events from the first fragment to the bus: EventBus.getDefault().postSticky(AnyEventType); 

Actualización : tal vez estoy equivocado acerca de su problema, había el mismo problema y se resuelve mediante la eliminación de ThreadEnforcer.ANY , puede probarlo.

También me gustaría añadir a la conversación que no se pueden declarar métodos @Subscribe en una interface o una @Subscribe , no serán llamados.

De los documentos de Otto :

El registro sólo encontrará métodos sobre el tipo de clase inmediata. A diferencia del bus de eventos de Guava, Otto no recorrerá la jerarquía de clases y agregará métodos de clases base o interfaces anotadas. Esta es una decisión explícita de diseño para mejorar el rendimiento de la biblioteca, así como mantener su código simple y sin ambigüedad.

EventBus by greenrobot admite esta característica: https://github.com/greenrobot/EventBus

  • RxAndroid, bus de eventos y ciclo de vida de la actividad
  • Model View Presenter con un EventBus, ¿cómo recuperar los eventos en Presenter?
  • Informe Leakcanary de pérdida de memoria usando Otto
  • Pasar datos de Actividad a Fragmento usando Otto
  • Cancelar el registro de los oyentes en onDestroy - ¿cuál es el daño / pueden tener fugas?
  • ¿Qué métodos de ciclo de vida de actividad son los mejores para registrar / anular el registro en el bus de eventos?
  • ¿Hay ventajas para cambiar a Otto de Broadcast events
  • ¿Cómo uso eficazmente un bus de eventos?
  • Otto / EventBus a través de múltiples procesos
  • NullPointerException con Otto y Dagger
  • Cómo saber si un suscriptor de Otto está registrado
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.