EventBus源码

介绍

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 )中;

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


示例源码


参考资料

  • 鸿洋 Android EventBus源码解析 带你深入理解EventBus
  • EventBus框架原理解析(结合源码)(上)
  • eventbus3.0 源码分析 super

你可能感兴趣的:(EventBus源码)