EventBus 源码阅读记录

284 阅读2分钟

总的来说,EventBus就是一个在注册时将所有类找出来(注解与反射),然后发送事件时,一个一个执行所有参数为事件类型的方法(反射);而粘性事件就是把粘性事件保存起来,再执行post方法(让已经注册过的类方法执行),最后在类注册时,再一个一个执行(即先发送事件,再注册),因为事件是保存在Map中,所以只有最后发送的事件是有效的

阅读代码遇到的难点

1.ThreadLocal

ThreadLocal而是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据, ThreadLocal在EvetBus中的作用是在post事件时,取出事件队列,如下图。每个不同的线程都有独立的数据。

ThreadLocal相当于维护了一个map(ThreadLocal.ThreadLocalMap),key就是当前Threadlocal的实例,value就是需要存储的对象。

每个线程中的ThreadLocalMap中可能有多个ThreadLocal对应的value。
每个thread 下有一个threadmap的引用,
Threadlocal 是使用 thread 操作ThreaLocaldMap的一个类

2.CopyOnWriteArrayList

  • 实现了List接口
  • 内部持有一个ReentrantLock lock = new ReentrantLock();
  • 底层是用volatile transient声明的数组 array
  • 读写分离,写时复制出一个新的数组,完成插入、修改或者移除操作后将新数组赋值给array
  • 并发安全且性能比Vector好

3.Handler、Looper、MessageQueue、Thread、Message

Message 在MessageQueue中,一个Thread只有一个Looper(Looper保存在Thread的ThreadLocalMap中),一个Looper对应一个MessageQueue;一个Thread有多个Handler, Message加入到MessageQueue中(MessageQueue.enqueueMessage),在Looper.loop()这个死循环中获取(MessageQueue.next())
在Android入口类中,会在主线程中加入Looper
Handler.post()、Handler.postDelayed()不会走Handler.handleMessage,而是走handleCallback, Handler.sendMessage()才会走Handler.handleMessage,mCallBack是在Handler初始化中可能会传进去的。(具体见下图)

为什么在主线程中Looper.loop()中死循环,程序不会ANR?
Android系统中所有的操作均通过Handler添加事件到事件队列,Looper循环去队列去取事件进行执行。如果主线程事件反馈超过了5秒则提示ANR。(如果后续没有操作,哪怕在主线程中一直Thread.sleep也不会导致ANR)