美文网首页
EventBus源码

EventBus源码

作者: jacky123 | 来源:发表于2016-07-10 23:11 被阅读40次

    介绍

    1.什么是EventBus

    想必每个入了门的Android开发者都多少对EventBus有过了解,EventBus是一个Android事件发布/订阅框架,通过解耦发布者和订阅者简化 Android 事件传递。

    EventBus 直译过来就是事件总线,它使用发布订阅模式支持组件之间的通信,不需要显式地注册回调,比观察者模式更灵活,可用于替换Java中传统的事件监听模式,EventBus的作用就是解耦,它不是通用的发布订阅系统,也不能用于进程间通信。

    最近EventBus刚好更新了3.0版本,事件的订阅已经从方法名换成了注解的方式。3.0版本将粘性事件以及订阅事件的优先级换了一种更好的实现方式,所以3.0版本中的注册就变得简单,只有一个register()
    方法即可.




    使用 EventBus3.0

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);
    }
    
    public void onEventBus(View view) {
        EventBus.getDefault().post(new Student(12, "helen"));
    }
    
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvenHaha(Student student) {
        Log.d(TAG, "ThreadMode.MAIN:thread info:" + Thread.currentThread() + ",bean info:" + student.toString());
    }
    
    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onEventPost(Student student) {
        Log.i(TAG, "ThreadMode.POSTING:thread info:" + Thread.currentThread() + ",bean info:" + student.toString());
    }
    
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onEventBackground(Student student) {
        Log.w(TAG, "ThreadMode.BACKGROUND:thread info:" + Thread.currentThread() + ",bean info:" + student.toString());
    }
    
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEventAsyn(Student student) {
        Log.e(TAG, "ThreadMode.ASYNC:thread info:" + Thread.currentThread() + ",bean info:" + student.toString());
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
    

    post一个obj,在ui线程。结合文档ThreadMode.java 的说明,可以知道:

    Paste_Image.png

    原理概述

    EventBus解耦的方式其实是使用了反射,我在调用register()方法的时候,获取到Subscription对象,EventBus就扫描调用Subscription类,将需要反射调用的方法信息记录下来,这些方法就是

    onEvent(),
    onEventMainThread(),
    onEventBackgroundThread()
    onEventAsync()。

    这些方法被记录以后,如果有人调用post()方法,就会在记录里面查找,然后使用反射去触发这些方法。反射触发方法的方式是调用Method类的invoke()方法。

     public Object invoke(Object obj, Object... args)  
    

    显然要我们需要1,Method对象,订阅者对象obj,还有参数对象args
    也就是说记录里面,对应一个订阅方法,起码要有上面三个参数。

    • 我们在register()的时候,目的是获得Subscription对象
    • 我们在post(Object obj)的时候,目的是将传入的obj和相应的Subscription对象一起封装成PendingPost对象
      将其放入队列里面排队,队列会不断取出元素,触发反射!

    扫描方法

    你只要记得一件事:扫描了所有的方法,把匹配的方法最终保存在subscriptionsByEventType(Map,key:eventType ; value:CopyOnWriteArrayList<Subscription> )中;

    eventType是我们方法参数的Class
    Subscription中则保存着subscriber, subscriberMethod(method, threadMode, eventType), priority;包含了执行改方法所需的一切。


    示例源码


    参考资料

    相关文章

      网友评论

          本文标题:EventBus源码

          本文链接:https://www.haomeiwen.com/subject/rxwdjttx.html