更新2019-01-16 EventBus 分析(Android)

闲得发慌,打算自己做一个注解+事件总线的android框架
就先从分析一下其他框架开始

贴一下EventBus的github地址

更新2019-01-16 EventBus 分析(Android)_第1张图片
image

EventBus特点

依赖注解(下面是详细在EventBus存在的可注解主题)

Annotation Feature
@Subscribe 订阅事件
ThreadMode Description NOTE
POSTING 直接执行 直接通过java.lang.reflect包的method.invoke执行(默认)
MAIN 在主线程执行 EventBus会先判断是否在主线程:是,则直接跟POSTING一样通过method.invoke直接执行;否,则压入mainPoster的队列里
MAIN_ORDERED 同样是在主线程执行 EventBus压入mainPoster的队列中
BACKGROUND 后台运行 EventBus会先判断是否在主线程:是,则压入backgroundPoster的队列里;否,则通过method.invoke直接执行
ASYNC 在单独一个线程中执行 由EventBusBuilder中的newCachedThreadPool执行

它不像xutils一样,拥有控件和控件事件上的注解
不过毕竟是可以跨android和Java的框架

EventBus is a publish/subscribe event bus for Android and Java.

也就不强求这个了(熟悉一下ClassLoader和InvocationHandlr,也可以自己加这些)

事件管理

这个事件的管理囊括了多线程,CopyOnWriteArrayList(java的concurrent包的一个优化算法),它自己建的队列PendingPostQueue,注解事件监听。

ok,那么详细来分析一下这个框架的源码

有几个重要的类或者接口需要看一下

1. EventBus和对应的建造者EventBusBuilder

2. 各种事件Poster

EventBus的实现是典型的建造者模式(当然也有一些工厂模式和代理模式在里面)

public static EventBusBuilder builder() {
      //返回一个新建的EventBusBuilder对象
      return new EventBusBuilder();
    }

在EventBusBuilder的中,创建了一个默认的可无线扩容的线程池newCachedThreadPool

//在EventBusBuilder中
  private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
...
  public EventBusBuilder executorService(ExecutorService executorService) {
        this.executorService = executorService;
        return this;
    }
...
//在异步事件AsyncPoster中
 public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        queue.enqueue(pendingPost);
        eventBus.getExecutorService().execute(this);
    }
...
//在后台事件BackgroundPoster中
  public void enqueue(Subscription subscription, Object event) {
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        synchronized (this) {
            queue.enqueue(pendingPost);
            if (!executorRunning) {
                executorRunning = true;
                eventBus.getExecutorService().execute(this);
            }
        }
    }

这个线程主要负责异步事件AsyncPoster和后台事件BackgroundPoster的执行,但在EventBus里还有POSTING,MAIN,MAIN_ORDERED这三个事件,那么它们又是靠什么线程来执行的呢?

这三者其实是基本一致的
只不过是MAIN和MAIN_ORDERED事件会先过一个isMainThread()方法

  private boolean isMainThread() {
        return mainThreadSupport != null ? mainThreadSupport.isMainThread() : true;
  }

那么它是怎么将事件放在主线程运行呢?

首先介绍一下Looper这个东西
简单点理解,Looper其实就是一个死循环,不停遍历内部是否含有未处理的Runnable
也是就是执行消息循环队列MessageQueue的一个线程
而且默认情况下,我们后来新建的线程都是没带消息循环队列MessageQueue

//创建一个Looper对象
Looper.prepare();
//开始执行Looper.loop
Looper.loop();
//返回主线程的Looper对象
Looper.getMainLooper();

这里我们就可以做是否主线程的判断了,但还是没有明白怎么把事件发到主线程上

其实这里应该补充一个东西,HandlerThread & Handler的原理了
(如果你有看过tensorflow的官方demo,就可以发现它的识别线程其实就是一个基于主线程Looper创建的一个HandlerThread)

//HandlerThread其实也是多线程的一种,只不过其他多线程基本都是java自带的,不存在Looper
//而HandlerThread是存于android.os包里的,带了Looper
HandlerThread handlerThread = new HandlerThread("线程名称");
//只有在启动这个线程,对应的Looper对象才能被生成,然后才可以创建以此Looper为底的handler(个人理解,可以把handler当作是Looper的一个外露接口)
handlerThread.start();
//以此Looper为底的handler
Handler handler = new Handler(handlerThread.getLooper());
OR
//以此Looper为底的handler,并且处理消息的分发
Handler handler = new Handler(handlerThread.getLooper(),new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                  ...
                  return false;
            }
        });

虽然,EventBus并没有用HandlerThread.....只是用了 Handler handler = new Handler(Looper.getMainLooper()); 而已!

EventBus的所有事件Poster基本都实现了Runnable(除了MAIN和MAIN_ORDERED事件外,这两个都拿去继承了Handler和实现Poster接口而已)
当然在每个事件Poster都有一个PendingPostQueue(EventBus自建带同步锁和延迟弹出的队列)在存储需要发送的消息(ps:下回再讲)

  /*提取消息准备发送*/
  /*@param event  为开发者自己创建需要传递的消息*/
  static PendingPost obtainPendingPost(Subscription subscription, Object event) {
        /*pendingPostPool为存储的消息的数组*/
        synchronized (pendingPostPool) {
            int size = pendingPostPool.size();
            if (size > 0) {
                PendingPost pendingPost = pendingPostPool.remove(size - 1);
                pendingPost.event = event;
                pendingPost.subscription = subscription;
                pendingPost.next = null;
                return pendingPost;
            }
        }
        return new PendingPost(event, subscription);
    }

未完待续...

你可能感兴趣的:(更新2019-01-16 EventBus 分析(Android))