JeremyLiao / LiveEventBus

:mailbox_with_mail:EventBus for Android,消息总线,基于LiveData,具有生命周期感知能力,支持Sticky,支持AndroidX,支持跨进程,支持跨APP
Apache License 2.0
3.87k stars 529 forks source link

关于页面复用之后的事件监听问题 #143

Open edwardZj opened 3 years ago

edwardZj commented 3 years ago

有这样的场景,比如有些activity或者fragment是复用的,并且同时会存在多个实例,而他们里面也都有事件监听,因此这时候发送事件,这些activity或者fragment都会收到并且处理,而很多时候,我只需要前台响应的这个activity或者fragment来处理接收事件, lifecycleObserverAlwaysActive并不能解决,因为这是一个全局的设置,并且很多时候需要接收Stoped之后的消息.同时,同一个事件,可能在不同的activity或者fragment都有监听,而这个消息只需要指定某一个activity或者fragment来处理,其他的不需要处理,(如某个按钮点击后做了一些处理最后发回一个事件,这个事件只需要当前按钮所在的activity或者fragment来处理,其他同样监听此事件的不应该处理. 所以需要有个功能,能指定activity或者fragment(或者view或者其他任何对象)来接收事件.我的方法是: public static void postSpecify(Object specify, String eventName, Object bean) { LiveEventBus.get(eventName).post(new SpecifyEvent(specify, bean)); } class SpecifyEvent { String specify; Object obj;

public SpecifyEvent(Object specify, Object obj) {
    this.specify = specify.getClass().getName() + "@" + specify.hashCode();
    this.obj = obj;
}

} //在监听的地方统一代理,做相应处理,一般来说,都是直接用owner做Specify,反正只要发送和监听的地方用同一个Specify就行,就能指定接收 private static Observer proxyObserver(LifecycleOwner owner, String eventName, Observer observe) { return new Observer() { @Override public void onChanged(@Nullable Object o) { //observe中如果crash,则之后的消息都会阻断,因为正在分发的状态没有重置,life框架以为分发没结束 try { if (owner != null) { // 初步解决解决activity销毁不及时的情况下,待销毁的activity依然能收到当前activity发出的事件,从而影响业务逻辑和性能,所以在事件分发器BaseEventBus底层做isFinishing判断,在activity进入finish之后,他和他的组件不再接收事件 2020/5/20 15:34 Activity act = getAct(owner); if (act == null) { return; } if (act != null && act.isFinishing()) { LiveEventBus.get(eventName).removeObserver(this); return; } //此事件仅被本activity内的observer监听,其他监听同样事件的不会收到 if (o != null && o instanceof SpecifyEvent) { if (!TextUtils.equals(((SpecifyEvent) o).specify, owner.getClass().getName() + "@" + owner.hashCode())) { return; } else { o = ((SpecifyEvent) o).obj; } } } if (observe instanceof EventObserver) { ((EventObserver) observe).onReceive(eventName, o); } else { observe.onChanged(o); } } catch (Exception e) { e.printStackTrace(); } } }; }

这样监听的地方方法都跟之前一样,需要特定接收就postSpecify,不需要就普通post

这个bug也可以顺便处理一下,我还有一些思路,可以加个好友沟通 //初步解决解决activity销毁不及时的情况下,待销毁的activity依然能收到当前activity发出的事件,从而影响业务逻辑和性能,所以在事件分发器BaseEventBus底层做isFinishing判断,在activity进入finish之后,他和他的组件不再接收事件

edwardZj commented 3 years ago