EventBus

1 什么是EventBus?  EventBus是Android下高效的发布/订阅事件总线机制。(官方描述)

相比较于同类型的有Handler,接口回调,广播

优点在于:代码简洁,没错就是简洁

缺点在于:难以维护,因为啊,当你的项目中多处使用了EventBus你会发现难以维护且难以追踪,并且还得为每种事件定义一个类(这个类就是数据的载体),用得多了就会导致代码结构的臃肿,所以对于EventBus毫无疑问它是强大的方便的简洁的,同时也请不要滥用


2 为什么会出现EventBus?EventBus没出现之前我们是怎么做的?

EventBus的出现就是为了让程序员偷懒,提高工作效率,因为实在是太方便了,EventBus没出现之前我们只能通过接口回调实现代码间的调用,使用Handler实现线程间的通信.

打个比方,之前我们如果想让Fragment调用Fragment里的方法,怎么做?  是不是只能通过中间人activity去操作?有了EventBus,定义一个事件类,然后发布事件,然后接收事件即可!三步走就搞定了,同时代码还非常简洁.


3 怎么使用EventBus?

EventBus在3.0之前是使用四个方法来进行使用,但是在3.0之后它是使用注解来方便开发者去使用,是不是更方便了有木有?

3.0之前使用四个固定的方法名来定义订阅者运行的模式,3.0之后增加了注解,在任意方法名上加上注解就可以了,这里只介绍3.0版本(二者本质无区别)

之所以3.0升级了使用注解很大原因是在于固定的方法名要通过反射去找到,对于混淆简直就是大杀器..当然这些细节不用太在意..我就随口说下...

介绍下注释的四种模式


与发送者在同一线程运行

@Subscribe(threadMode = ThreadMode.POSTING)
不论发送者在哪个线程,都会运行在主线程(用得最多的也就是这个,多用于更新UI, 异步下载,上传,数据库读写)

@Subscribe(threadMode = ThreadMode.MAIN)
不论发送者在哪个线程都会运行在子线程--- 细节:如果发送者运行在主线程,那么方法就会运行在一个线程池中创建的一条线程中,如果发送者在子线程,那么方法会运行在同一线程

@Subscribe(threadMode = ThreadMode.BACKGROUND)
不论发送者在哪个线程,方法永远在线程池创建的子线程执行(多用于多线程任务处理如多线程下载)

@Subscribe(threadMode = ThreadMode.ASYNC)


是不是感觉超级震撼?居然都不需要拿到对象就可以调用到类里面的方法,感觉就像是人类第一次相隔万里就能通话?


写了一个小Demo


当我们点击左边的Fragment条目就会向右边的Fragment发送消息,使用之前呢,老规矩,三步走

1 在需要接收消息的勒种进行注册以及解绑,注册一般在onCreate方法解绑一般在onDestory

EventBus.getDefault().register(this);
EventBus.getDefault().unregister(this);

2在需要接收消息的方法上加上注解

@Subscribe(threadMode = ThreadMode.POSTING)
    public void setText1(EventMsg  text){
        Log.e("收到消息",Thread.currentThread().getName()+" ID:"+Thread.currentThread().getId());
        mViewById.setText(text.getMsg());
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void setText2(EventMsg  text){
        Log.e("收到消息",Thread.currentThread().getName()+" ID:"+Thread.currentThread().getId());
        mViewById.setText(text.getMsg());
    }
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void setText3(EventMsg  text){
        Log.e("收到消息",Thread.currentThread().getName()+" ID:"+Thread.currentThread().getId());
        mViewById.setText(text.getMsg());
    }
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void setText4(EventMsg  text){
        Log.e("收到消息",Thread.currentThread().getName()+" ID:"+Thread.currentThread().getId());
        mViewById.setText(text.getMsg());
    }
 @Subscribe(threadMode = ThreadMode.POSTING)
    public void setText5(EventMsg2 text){
        Log.e("收到消息1",Thread.currentThread().getName()+" ID:"+Thread.currentThread().getId());
        mViewById.setText(text.getMsg());
    }


3 发送消息,发送的消息必须需要一个实体类,这个实体类就是用来传递数据的,这也是我们确定发送者发出的数据由谁来接收

        switch (position) {
            case 0://主线程发消息
                Log.e("主线程发送消息",Thread.currentThread().getName()+" ID:"+Thread.currentThread().getId());
                EventBus.getDefault().post(new EventMsg("主线程发送来的消息"));
                break;
            case 1://子线程发消息

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Log.e("子线程发送消息",Thread.currentThread().getName()+" ID:"+Thread.currentThread().getId());
                        EventBus.getDefault().post(new EventMsg("子线程发送来的消息"));
                    }
                }).start();
                break;
            case 2://主线程发消息2
                EventBus.getDefault().post(new EventMsg2("主线程发送来的消息2"));
                break;
        }

当我们点击左边的条目,右边就会接收到数据,但是要注意右边的四个方法会有方法运行在子线程,而我又在子线程更改UI了,这是不可取的,但是为了好看,我就没删,大家注意即可

当我点击左边的,条目一主线程发送数据,右边的五个方法,其中四个都会接收到,因为载体都是一样的,是EventMsg,第五个方法的载体是EventMsg2,所以接收不到

当我点击第一个条目时,log如下

由主线程发出的消息有两条是执行在主线程中以及两条子线程中,当然接收顺序是不固定的,原谅我没有把方法名加入Log中,否则就会很明显


点击第二个条目,由子线程发出消息

可以发现只有一条运行在主线程,剩下的都运行在子线程中,看到pool了么,这是线程池中线程,所以线程的管理也并不需要我们去管理,都已经有EventBus去管理了


点击第三个条目时,只有一个方法接收到.因为发出的消息载体时EventMsg2,接收的方法载体只有一个EventMsg2

至于在服务中,都是一样没有区别,一亲我们要调用服务里的方法腰痛果onBind方法作为媒介,现在哦度一去不复返了,这里不做过多阐述,简单说一下EventBus的原理

1 发布者通过post发送消息事件,发布到事件总线(可以理解成消息队列)

2 收到消息后遍历所有已经注册的订阅者

3 订阅者收到消息后,执行方法,参数类型一致才会被执行(载体)

大致简单的说了下,以后会对EventBus的源码进行解析的

到这里基本就讲完了,关于源码的分析就要抽时间专门写一篇博客了,EventBus用起来非常方便,也是github最火的开源项目,大家可以用到自己的项目中去,你一定不会失望

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值