小言_互联网的博客

EventBus的优化——KeventBus

304人阅读  评论(0)

一、前言

eventbus3.0的优缺点分析:

eventbus基于观察者模式,用很少的代码,帮我们实现很多功能,使我们的代码变得很优雅。但是大面积的使用eventbus之后,会发现一些很严重的问题

  • 需要创建很多的类来区分订阅方法,订阅的方法越多,类越多,代码越多,apk的体积越大
  • 以类来贯穿这个事件传递的方式,广播方式发送问题后,排查事件源或订阅方法的难度比较大
  • 需要写很多的订阅方法,订阅方法满天飞,很容易发生dex方法数超出
  • 发送的广播无法收到返回值
  • 不知道private的订阅方法,不知道eventbus为什么要这么设计
  • 明明不用发送数据,只是通知,也需要传递一个类
  • 无法取消单独的某一个订阅的方法

围绕这个上面几个问题,我在eventbus的基础上进行了改善。


二、改善说明: 基于android eventbus 3.0 版本优化:

  • 优化前期以类为区分监听接收对象,需要创建很多类,优化后采用字符串方式作为事件event-key区分代替以类的方式,避免创建太多类,减少代码量,比较优雅,本思想也参考ios通知的实现。

  • 支持返回值,支持private和static的方法

  • 优化前,订阅者需要订阅很多监听方法来区分分类,优化后可以减少监听方法,在一个方法或多个方法里面进行分类判断即可,思想来自handler

  • 优化前维护难,表现在不清楚事件发生源,优化后,可以统一管理事件vent key,方便管理查找bug

  • 支持只发送事件的功能

  • 支持冷冻事件方法,和解除冷冻事件的方法

其他方面如Subscribe订阅方法,线程模式的,粘性事件等的处理均和eventbus3.0的处理一致。

项目使用: 
androidstudio gradle 引入:implementation ‘com.github.chenjk-520:keventbus:1.1’
项目开源地址:github地址
,如果觉得好用就给个Star或给个打赏吧。如果需要改进的地方,清在下面评论或发送私信到我的邮件13544216361@163.com




三、使用说明

和eventbus3.0版本的使用方式差不多,是eventbus3.0改进,下面看看怎么使用

  • 了解使用之前先了解一下其中一个关键的类EventMessage
     private T msg;
     private String event;
     private int arg;
     private CallBack callBack;

msg是我们需要发送的数据,可以是任何数据
event是我们一个事件对应的event,通过这个event我们可以找到订阅的方法。
arg,是event的在一次分类
callBack 是处理发送广播后的回调。

1.注册事件与取消注册事件

注册事件:

  KeventBus.getDefault().register(this);

取消注册事件:
 
  KeventBus.getDefault().unregister(this);

2. 只使用event-key,不发送数据

发送事件:

 KeventBus.getDefault().post(TestKey.SAY_HELLO);

接收事件:

@Subscribe(event = TestKey.SAY_HELLO,threadMode = ThreadMode.MAIN)
public void hello(EventMessage<String> msg){
    Log.i("TAG",msg.getEvent());
}
其中post事件TestKey.SAY_HELLO,与@Subscribe的event = TestKey.SAY_HELLO一一对应才可以接收到

3. 使用event-key,并发送数据

发送事件:

 KeventBus.getDefault().post(new EventMessage<>("say hello!",TestKey.SAY_HELLO));

这里的构造函数参数分别是msg,event

接收数据:

  @Subscribe(event = TestKey.SAY_HELLO,threadMode = ThreadMode.MAIN)
  public void hello(EventMessage<String> msg){
      Log.i("TAG",msg.getMsg());
  }

4. 使用event-key,并发送数据, 在同一订阅方法里面再区分,有点类似handler的message,event相当于是what属性,arg也跟message的arg一样

发送事件1:

     KeventBus.getDefault().post(new EventMessage("data==1",TestKey.SAY_HELLO,1));

发送事件2:

     KeventBus.getDefault().post(new EventMessage("data==2",TestKey.SAY_HELLO,2));

这里的构造函数参数分别是msg,event,arg

接收事件:

      @Subscribe(event = TestKey.SAY_HELLO,threadMode = ThreadMode.MAIN)
      public void hello34(EventMessage<String> msg){
        if (msg.getArg() == 1){
            Toast.makeText(this,msg.getMsg(),Toast.LENGTH_SHORT).show();
        }else if(msg.getArg() == 2 ){
            Toast.makeText(this,msg.getMsg(),Toast.LENGTH_SHORT).show();
        }
     }

5. 支持发送订阅消息后回调

发送订阅消息:

        KeventBus.getDefault().post(new EventMessage<String>("测试data",TestKey.SAY_HELLO, new EventMessage.CallBack<String>() {
                        @Override
                        public void onCall(String result, int arg) {
                            //在这里处理回调数据
                            Log.i("TAG",result);
                        }
                    }));

接收事件:

        @Subscribe(event = TestKey.SAY_HELLO4,threadMode = ThreadMode.ASYNC,enback = true)
        private String hello5(EventMessage msg){
            Log.i("TAG",msg.getMsg());
            return "测试返回值";
        }                       

注意:
1.接收事件需要加上enback = true
2.这里的回调之后的是接收事件的线程,如果在主线程里面发出的,在子线程接收并返回的事件,回调的方法是接收方法的线程,如果需要toast的话,需要自己切换到主线程再处理

5. 支持冷冻事件和激活事件

说明: 冷冻事件后,发送相对应的事件,订阅的方法将不能接收到这个时间,但这个订阅的方法并没有真的移除掉,可以通过重新激活这个方法,下次发送便可以再接收到

冷冻方法:

      KeventBus.getDefault().freezeSubscribeEvent(TestKey.SAY_HELLO);

激活方法:

     KeventBus.getDefault().activeEvent(TestKey.SAY_HELLO);  

转载:https://blog.csdn.net/qq_30207527/article/details/105970919
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场