Android EventBus 封装

0
回复
138
查看
[复制链接]

191

主题

195

帖子

3542

安币

手工艺人

发表于 2019-5-9 10:45:01 | 显示全部楼层 |阅读模式
如果对本篇文章感兴趣,请前往,原文地址:http://www.apkbus.com/blog-822724-80014.html

[EventBus](https://link.jianshu.com?t=https://github.com/greenrobot/EventBus)是一款针对Android优化的发布/订阅事件总线。可以替代广播、```startActivityForResult```、```Handler```、异步回调等来实现各组件间、组件与后台线程间的通信。它的优点是开销小,代码更优雅,以及将发送者和接收者解耦。通常我们在使用```EventBus```的时候都是直接需要接收通信的```Activity/Fragment```中通过```EventBus.getDefault().register(this)```订阅事件,在需要发起通信的逻辑直接调用```EventBus.getDefault().post(Object event)```来发布事件。但是要是一个项目中有很多地方都使用```EventBus```来通信,比如重新登录后更新各个页面的登录状态,或者是接收到通知更新消息提示等,都这样直接使用的话代码重复率很高,并且呢,如果以后升级或者更换```EventBus```时,各个地方都要修改,这就比较麻烦了。因此我一般是将```EventBus```的发布和订阅封装到```BaseActivity/BaseFragment```中。在Gradle中添加```EventBus```依赖:```compile 'org.greenrobot:eventbus:3.0.0'```封装一下```EventBus```的订阅、取消订阅、发布等方法:```public class EventBusUtil {    public static void register(Object subscriber) {        EventBus.getDefault().register(subscriber);    }    public static void unregister(Object subscriber) {        EventBus.getDefault().unregister(subscriber);    }    public static void sendEvent(Event event) {        EventBus.getDefault().post(event);    }        public static void sendStickyEvent(Event event) {        EventBus.getDefault().postSticky(event);    }    // 其他}```在```BaseActivity/BaseFragment```中的```onCreate```和```onDestroy```方法中订阅和取消订阅,这里添加了一个```isRegisterEventBus()```方法,默认返回```false```,即不订阅```EventBus```,子类```Activity/Fragment```如果需要订阅的话复写这个方法并返回```true```即可。```@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    if (isRegisterEventBus()) {        EventBusUtil.register(this);    }}/** * 是否注册事件分发 * * @return true绑定EventBus事件分发,默认不绑定,子类需要绑定的话复写此方法返回true. */protected boolean isRegisterEventBus() {    return false;}@Overridepublic void onDestroy() {    super.onDestroy();    if (isRegisterEventBus()) {        EventBusUtil.unregister(this);    }}```定义事件```Event```:```public class Event {    private int code;    private T data;    public Event(int code) {        this.code = code;    }    public Event(int code, T data) {        this.code = code;        this.data = data;    }    public int getCode() {        return code;    }    public void setCode(int code) {        this.code = code;    }    public T getData() {        return data;    }    public void setData(T data) {        this.data = data;    }}```通过泛型``````指定事件通信过程中的数据类型,```code```为事件码,使用的时候给不同的事件类型指定不同的```code```。在```BaseActivity\BaseFragment```中添加接收到```EventBus```的方法:```/** * 是否注册事件分发 * * @return true绑定EventBus事件分发,默认不绑定,子类需要绑定的话复写此方法返回true. */protected boolean isRegisterEventBus() {    return false;}@Subscribe(threadMode = ThreadMode.MAIN)public void onEventBusCome(Event event) {    if (event != null) {        receiveEvent(event);    }}@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)public void onStickyEventBusCome(Event event) {    if (event != null) {        receiveStickyEvent(event);    }}/** * 接收到分发到事件 * * @param event 事件 */protected void receiveEvent(Event event) {}/** * 接受到分发的粘性事件 * * @param event 粘性事件 */protected void receiveStickyEvent(Event event) {}```根据自己项目的需求,在订阅了```EventBus```的```Activity/Fragment```中复写```receiveEvent(Event event)```或```receiveStickyEvent(Event event)```来处理接收到事件后的逻辑。这里也可以不用在```BaseActivty/BaseFragment```中添加接受事件的方法(因为添加了过后不能确定的子类的```Event```泛型)。那么就直接在订阅的```Activity/Fragment```中给接收事件的方法添加```EventBus```对应的事件接受注解,并指定参数Event的泛型。```@Subscribe(threadMode = ThreadMode.MAIN)public void onEventReceived(Event event) {    if (event != null && event.getCode() == C.EventCode.C) {        User user = event.getData();    }}```在给定```Event```的```code```的时候最好在常量池中定义一个类专门用来定义不同类型的```EventBus```的```code```,这样在接收到```EventBus```的地方可以根据这些```code```值来判断```Event```的来源。```public final class C {    // EventBus Code    public static final class EventCode {        public static final int A = 0x111111;        public static final int B = 0x222222;        public static final int C = 0x333333;        public static final int D = 0x444444;        // other more    }}```使用示例:在```MainActivity```中复写```isRegisterEventBus()```并返回```true```注册```EventBus```,复写```receiveEvent(Event event)```接收发布的事件。```@Overrideprotected boolean isRegisterEventBus() {    return true;}@Overrideprotected void receiveEvent(Event event) {    // 接受到Event后的相关逻辑    switch (event.getCode()) {        case C.EventCode.A:Log.d("EventBus", "接收到A类型的Event");break;        case C.EventCode.B:Log.d("EventBus", "接收到B类型的Event");break;        case C.EventCode.C:Log.d("EventBus", "接收到B类型的Event,携带User");User user = (User) event.getData();break;        case C.EventCode.D:Log.d("EventBus", "接收到D类型的Event,携带News");News news = (News) event.getData();break;    }}```在```receiveEvent(Event event)```根据对应的事件的```code```,判断通信的数据来源和传递的数据类型,以完成对应的逻辑。在```InfoActivity```中发送事件,```InfoActivity```只发送不需要接收```Event```的话就不注册,也不用复写```isRegisterEventBus()```和```receiveEvent(Event event)```方法了。```public void sendEventA(View view) {    EventBusUtil.sendEvent(new Event(C.EventCode.A));}public void sendEventB(View view) {    EventBusUtil.sendEvent(new Event(C.EventCode.B));}public void sendEventC(View view) {    Event event = new Event(C.EventCode.C, new User());    EventBusUtil.sendEvent(event);}public void sendEventD(View view) {    Event event = new Event(C.EventCode.D, new News());    EventBusUtil.sendEvent(event);}```通过上面的方式,将```EventBus```封装到```BaseActivity/BaseFragment```中,使得EventBus和项目解耦更加彻底,同时在需要使用的子Activity/Fragment中只需要复写```isRegisterEventBus()```和```receiveEvent(Event event)```即可,不用每个地方都去订阅和取消订阅。并且给```Event```给定```code```和泛型能够很好的区分不同的事件来源和数据类型。源码:[https://github.com/xiaoyanger0825/EventBusExample](https://link.jianshu.com?t=https://github.com/xiaoyanger0825/EventBusExample)  继续阅读全文



想在安卓巴士找到更多优质博文,可移步博客区

如果对本篇文章感兴趣,请前往,
原文地址:
http://www.apkbus.com/blog-822724-80014.html
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )