关于EventBus的白话总结

起初是看到了@亚运的帖子,初步了解和使用了EventBus包,让我感到很惊奇,他没有使用Handler,BroatCast就可以自由的传递消息。@鸿洋大神提到他包含四个部分,订阅者、发布者、事件、总线。下面将一一做简单解释;

先贴一下最简单的EventBus使用的代码:

在OnCreate中有一行EventBus.getDefault().register(this);这里是注册EventBus,所传的参数为当前类实例。也就是事件的订阅;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);//注册
initView();
}


在OnDstroy中注销注册的EventBus,EventBus.getDefault().unregister(this);这也就是事件的取消订阅;

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
EventBus.getDefault().unregister(this);//注销
}


在点击事件中发送要传递的值,传递最简单字符串,也就是事件的发布;

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v.getId()==R.id.btn){
EventBus.getDefault().post("传的值");
}
}


此方法用于接收事件发布者发送或者说传递的值,为什么这个方法名要写成onEvent...这个后面会做解释;

  public void onEventMainThread(String str){
text.setText(str);
}

所有代码就这么多,这么简单易懂,这也是我写这个帖子的初衷,就是简单易懂,仅此而已。在这段简单的代码中我们没有看到Handler,没有看到广播,而且在主线程(UI线程)中更新了UI。

下面我们解释一下大家的一点:

首先是注册:EventBus.getDefault().register(this);

已公布的注册方法有四个:

public void register(Object subscriber) {  
       register(subscriber, DEFAULT_METHOD_NAME, false, 0);  
   }  
public void register(Object subscriber, int priority) {  
       register(subscriber, DEFAULT_METHOD_NAME, false, priority);  
   }  
public void registerSticky(Object subscriber) {  
       register(subscriber, DEFAULT_METHOD_NAME, true, 0);  
   }  
public void registerSticky(Object subscriber, int priority) {  
       register(subscriber, DEFAULT_METHOD_NAME, true, priority);  
   } 

细心的朋友可以看到他们都调用了一个方法:

private synchronized void register(Object subscriber, String methodName, boolean sticky, int priority) {  
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriber.getClass(),  
                methodName);  
        for (SubscriberMethod subscriberMethod : subscriberMethods) {  
            subscribe(subscriber, subscriberMethod, sticky, priority);  
        }  
    }  

四个参数

subscriber 是我们扫描类的对象,也就是我们代码中常见的this;

methodName 这个是写死的:“onEvent”,用于确定扫描什么开头的方法,可见我们的类中都是以这个开头。

sticky 这个参数,解释源码的时候解释,暂时不用管

priority 优先级,优先级越高,在调用的时候会越先调用。

看到其源码部分你会发现,首先它会得到这类的所有的方法,然后去遍历每一个方法,分别判断了是否以onEvent开头,是否是public且非static和abstract方法,是否是一个参数。如果都复合,才进入封装的部分。当符合要求的时候就会封装到一个Map中,Map的键就是类类型Class类型,而值就是onEvent开头的方法中的参数类型,在给出的代码中就是String,这个String类型为以后的Post方法埋下伏笔。

那么很多同学一定对 onEventMainThread中onEvent后面为什么是MainThread感兴趣,看了一下几行源码应该就懂了:

private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {  
        switch (subscription.subscriberMethod.threadMode) {  
        case PostThread:  
            invokeSubscriber(subscription, event);  
            break;  
        case MainThread:  
            if (isMainThread) {  
                invokeSubscriber(subscription, event);  
            } else {  
                mainThreadPoster.enqueue(subscription, event);  
            }  
            break;  
        case BackgroundThread:  
            if (isMainThread) {  
                backgroundPoster.enqueue(subscription, event);  
            } else {  
                invokeSubscriber(subscription, event);  
            }  
            break;  
        case Async:  
            asyncPoster.enqueue(subscription, event);  
            break;  
        default:  
            throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);  
        }  
    }  

具体的解释请点击:http://blog.csdn.net/lmj623565791/article/details/40920453

下面说一下Post函数EventBus.getDefault().post("传的值");

我这里为了通俗易懂,写的特别的low,大家见谅。

那么是怎么onEventMainThread方法是怎么知道有人给他传递了一个字符串的呢?大家还记得注册后封装的Map吗?Map<Class,String>,其实最后的Map应该是这样的Map<Class , Map<MethodName , ValueType>>,首先根据注册的类名找到onEvent方法名和数值类型的Map,然后根据Post的数据类型找到对应的onEvent方法,所以onEventMainThread就能够接收到所传递的值了。

好奇心比较浓的朋友一定在想,内部究竟是怎么轮询onEvent方法?究竟是怎么发送给UI线程Post过来的值的?

算了还是解释一下onEvent方法吧,我这里只说一下MainThread:

case MainThread:

首先去判断当前如果是UI线程,则直接调用;否则: mainThreadPoster.enqueue(subscription, event);把当前的方法加入到队列,然后直接通过handler去发送一个消息,在handler的handleMessage中,去执行我们的方法。说白了就是通过Handler去发送消息,然后执行的。

这是鸿洋大神的总结,说的比唱的都完美,大家这回懂了吧,依然是你熟悉的Handler只是被封装的完美无瑕。

就到这里吧,这是我的第二个帖子,我个人正处在玩命赚首付的阶段,时间有限,希望大家多多提出宝贵意见,我会一一回答大家的建议和疑问的,下节应该会写Android空间数据库Spatialite的帖子。

最后在这里感谢亚运同学和鸿洋大神!!






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值