Android各组件/控件间通信利器之EventBus
实际项目开发过程中,经常遇到如下场景:不同的应用程序组件的控件间具有一定的相互关联性,其中用户对后者进行的某种操作会引起前者的相应改变。举一个具体的场景:以糗事百科为例,在糗事列表页和详情页页,对于每个糗事而言,布局基本一致,在详情页点击了个赞,赞的数量增加,同时赞的图标发生了变化,此时返回到列表页,此糗事上的赞图标以及数量与刚刚详情页的需要保持一致。在举一个例子,对于多个底部导航tab下的资讯类阅读app,在咨询详情页点击了收藏,然后收藏成功,此时回到底部tab中的个人中心,假如个人中心中有我的收藏,同时后面显示的是收藏数量,此时此收藏数量需要同于于刚刚用户所进行的收藏/取消收藏而即时更改数字。凡此种种,类似需求场景非常常见。
有时候,当此类需求相对简单时,通过接口以实现回调等方式可以完成,但是当不同组件/控件之间的关系纷繁复杂时,基于接口的方案不仅使得代码非常繁琐,同时是的程序逻辑很混乱,基于此,EventBus,为此类需求的实现提供了非常方便的方案。
网上已经有不少EventBus的使用介绍,在此简单介绍下完整的使用流程。
1. 首先定义事件基类(其实不定义也可以,定义后的好处在于在同一个回调函数中直接依据不同的子类事件类型可以直接继续逻辑上的处理,代码和逻辑更加简洁清晰)
public class BaseEvent { }
2. 定义具体的事件类型(以上述收藏事件为例)
public class FavorEvent extends BaseEvent { private int did; public FavorEvent() { } public FavorEvent(int did) { this.did = did; } public int getDid() { return did; } public void setDid(int did) { this.did = did; } }
3. 在需要监听此收藏事件的地方向EventBus注册事件监听器
EventBus.getDefault().register(this);
4. 当需要取消注册事件监听器时
EventBus.getDefault().unregister(this);
注:Android中,当遇到如EventBus中的register时,一般的,相应都会有unregister逻辑。且经常register与unregister逻辑相互对应,处在如Activity等组件的不同生命周期中。这是因为EventBus(其他也类似)在注册时由于是采用硬引用,存在潜在的内存泄露问题,而在相应生命周期中(如onDestroy)取消注册,即可消除可能潜在的内存泄露问题。
5. 当事件发生时,需要通知相应事件监听器进行相应逻辑处理
1 // 告知EventBus进行了收藏操作,让其通知相关感兴趣方(主要的是通知个人中心页面改变我的收藏数量) 2 EventBus.getDefault().post(new FavorEvent());
6. 其他组件/监听器具体事件逻辑
public void onEvent(BaseEvent event) { // 接收收藏事件通知,同步处理收藏数字 if (event instanceof FavorEvent) { // 即时更新收藏的数量(从sqlite中取得收藏数量) updateFavorNum(); } else if(..){ ... } }
整个的使用流程主要也就这么多了,其中,关于子线程和UI线程之间等亦可进行类似事件通知,网上此类资料很多,不再赘述了