EventBus源码解析(一)

EventBus事件总线框架

EventBus项目地址
EventBus源码解析(二)
EventBus源码解析(三)EventBus类
EventBus实战
自定义RxBus + RxRelay
RxRelay源码解析

EventBus基于事件的订阅和推送,实现Activity/Fragment之间的通信。
主要角色:

  • Event 传递的事件对象,自定义的一个类,封装了要传递的信息。
  • Publisher 事件的发布者EventBus,可以在任意线程任意位置发送事件。
  • Subscriber 事件的订阅者Activiyt/Fragment。
  • ThreadMode 定义在何种线程中发送事件。
    EventBus源码地址
    源码解析:

1.Subscription类

/**
 * 订阅者信息
 */
final class Subscription {
    final Object subscriber;    //订阅者
    final SubscriberMethod subscriberMethod;    //订阅方法
    volatile boolean active;    //是否在订阅状态,EventBus#unregister(Object)} is false

    Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
        this.subscriber = subscriber;
        this.subscriberMethod = subscriberMethod;
        active = true;
    }
}

2.ThreadMode枚举类

public enum ThreadMode {
    /**
     * Subscriber将在同一线程中直接调用,其用于发送事件. 默认.
    */
    POSTING,

    /**
     * 主线程调用,注意防止阻塞线程.
     */
    MAIN,

    /**
     * 主线程调用,有序,避免了阻塞
     */
    MAIN_ORDERED,

    /**
     * 若在主线程调用将启用一条后台线程;若在其他线程调用,直接在当前线程调用
     */
    BACKGROUND,

    /**
     * 异步线程,不会造成阻塞,用于耗时较长
     */
    ASYNC
}

3.MainThreadSupport 接口

/**
 * 主线程支持
 */
public interface MainThreadSupport {

    boolean isMainThread();

    Poster createPoster(EventBus eventBus); //创建一个Poster

    /**
     * 主线程支持类
     */
    class AndroidHandlerMainThreadSupport implements MainThreadSupport {

        private final Looper looper;

        public AndroidHandlerMainThreadSupport(Looper looper) {
            this.looper = looper;
        }

        @Override
        public boolean isMainThread() {
            return looper == Looper.myLooper();     //返回是主线程
        }

        @Override
        public Poster createPoster(EventBus eventBus) {     //创建一个主线程发射器
            return new HandlerPoster(eventBus, looper, 10);
        }
    }
}

4.SubscriberMethod

/**
 * 订阅方法信息
 */
public class SubscriberMethod {

    final Method method;    //订阅方法
    final ThreadMode threadMode;    //指定发送事件的线程模式
    final Class<?> eventType;   //订阅事件的类型
    final int priority; //订阅者级别
    final boolean sticky;   //是否接收sticky事件
    
    public SubscriberMethod(Method method, Class<?> eventType, ThreadMode threadMode, int priority, boolean sticky) {
        this.method = method;
        this.threadMode = threadMode;
        this.eventType = eventType;
        this.priority = priority;
        this.sticky = sticky;
    }
}    

5.SubscriberMethodFinder

/**
 * 查找订阅者的所有订阅方法
 */
class SubscriberMethodFinder {
...省略部分代码
    //订阅此事件的所有方法    key:eventType  value:方法集合
    private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();
    private final boolean ignoreGeneratedIndex; //是否忽略注解

    //以订阅者类型 查找它的 所有订阅者方法信息
    List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
        List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
        if (subscriberMethods != null) {
            return subscriberMethods;
        }
        //若忽略注解,则反射出方法
        if (ignoreGeneratedIndex) {
            subscriberMethods = findUsingReflection(subscriberClass);
        } else {
            subscriberMethods = findUsingInfo(subscriberClass);
        }
        if (subscriberMethods.isEmpty()) {
            throw new EventBusException("Subscriber " + subscriberClass
                    + " and its super classes have no public methods with the @Subscribe annotation");
        } else {
            METHOD_CACHE.put(subscriberClass, subscriberMethods);
            return subscriberMethods;
        }
    }

    //订阅此事件的所有方法清空
    static void clearCaches() {
        METHOD_CACHE.clear();
    }

6.PendingPost

**
 * 待发送事件,这个事件将会被加入事件池
 * 封装了事件event,订阅者信息subscription
 */
public class PendingPost {

    //事件池
    private final static List<PendingPost> pendingPostPool = new ArrayList<>();  //事件池

    Object event;   //事件
    Subscription subscription;  //订阅信息
    PendingPost next;

    private PendingPost(Object event, Subscription subscription) {
        this.event = event;
        this.subscription = subscription;
    }

    /**
     * 获取一个指定subscription和event的待发送事件PendingPost
     * @param subscription  订阅者信息
     * @param event 事件
     */
    static PendingPost obtainPendingPost(Subscription subscription, Object event) {
        synchronized (pendingPostPool) {
            int size = pendingPostPool.size();
            if (size > 0) {
                //取出最后一个位置的PendingPost向其赋值
                PendingPost pendingPost = pendingPostPool.remove(size - 1);
                pendingPost.event = event;
                pendingPost.subscription = subscription;
                pendingPost.next = null;
                return pendingPost;
            }
        }
        //若事件池为空,创建一个新的PendingPost
        return new PendingPost(event, subscription);
    }

    //释放这个待发送事件PendingPost
    static void releasePendingPost(PendingPost pendingPost) {
        pendingPost.event = null;
        pendingPost.subscription = null;
        pendingPost.next = null;
        synchronized (pendingPostPool) {
            // 不要让事件池无限增长
            if (pendingPostPool.size() < 10000) {
                pendingPostPool.add(pendingPost);
            }
        }
    }
}

7.PendingPostQueue

/**
 * 同步发送事件队列,包含两个PendingPost
 */
public class PendingPostQueue {

    private PendingPost head;
    private PendingPost tail;

    //执行发送指定的pendingPost
    synchronized void enqueue(PendingPost pendingPost) {
        if (pendingPost == null) {
            throw new NullPointerException("null cannot be enqueued");
        }
        //若已经有两个pendingPost待发送,替换tail为我指定发送的pendingPost,并存入tail.next
        if (tail != null) {
            tail.next = pendingPost;
            tail = pendingPost;
            //若队列为空,直接入队列head,tail都为pendingPost
        } else if (head == null) {
            head = tail = pendingPost;
        } else {
            throw new IllegalStateException("Head present, but no tail");
        }
        notifyAll();
    }

    //取出head处pendingPost,head和tail为空
    synchronized PendingPost poll() {
        PendingPost pendingPost = head;
        if (head != null) {
            head = head.next;
            if (head == null) {
                tail = null;
            }
        }
        return pendingPost;
    }

    //递归调用,每隔一段时间拉取一次PendingPost
    synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException {
        if (head == null) {
            wait(maxMillisToWait);
        }
        return poll();
    }
}

8.Poster接口

/**
 * 发射器:发送event事件
 */
public interface Poster {

    /**
     * 执行发送/订阅
     * @param subscription  订阅者信息
     * @param event 订阅的事件
     */
    void enqueue(Subscription subscription, Object event);
}

9.AsyncPoster异步,BackgroundPoster后台,HandlerPoster主线程

/**
 * 异步发送事件,反射调用订阅者的订阅方法,来订阅event。
 */
public class AsyncPoster implements Runnable,Poster {

    private final PendingPostQueue queue;   //待发送队列
    private final EventBus eventBus;

    AsyncPoster(EventBus eventBus) {
        this.eventBus = eventBus;
        queue = new PendingPostQueue();
    }

    /**
     * 执行发送
     * @param subscription  已经调用subscribe形成订阅
     * @param event
     */
    public void enqueue(Subscription subscription, Object event) {
        //封装subscription和event为待发送事件pendingPost
        PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
        //入队列
        queue.enqueue(pendingPost);
        //将此异步发送线程(run()方法)放入线程池执行
        eventBus.getExecutorService().execute(this);
    }

    @Override
    public void run() {
        //从队列拉取要发送的pendingPost
        PendingPost pendingPost = queue.poll();
        if(pendingPost == null) {
            throw new IllegalStateException("No pending post available");
        }
        //反射调用订阅者的订阅方法,来订阅event。即形成一个订阅通路
        eventBus.invokeSubscriber(pendingPost);
    }
}
发布了37 篇原创文章 · 获赞 7 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览