EventBus(二getDefault())

EventBus(二getDefault()分析)

之前我们简单介绍了EventBus如何使用,这里从getDefault()方法当作切入点。正如我们我们所知道的,我们使用EventBus都是使用这个方法拿到实例的,可是有什么用:

/**
 * Convenience singleton for apps using a process-wide EventBus instance.
 */
// 设立用的是单例模式
public static EventBus getDefault() {
    EventBus instance = defaultInstance;
    if (instance == null) {
        synchronized (EventBus.class) {
            instance = EventBus.defaultInstance;
            if (instance == null) {
                instance = EventBus.defaultInstance = new EventBus();
            }
        }
    }
    return instance;
}


// 理论上单例模式构造函数是私有的,这个是公开的
// EventBus并不是只有一条总线,还有其他的总线,订阅者可以订阅到不同的EventBus上,不同的EventBus发送数据是完全隔离开的
public EventBus() {
    // 这个就是我们经常使用的,使用builder构造实例
    this(DEFAULT_BUILDER);
}

// 很明显,这个是使用了构建者模式
EventBus(EventBusBuilder builder) {
    logger = builder.getLogger();
    // 这个以事件类型为key(可以理解成Event.class),subscription(封装的有订阅者),通过事件类型找到相关的订阅者
    subscriptionsByEventType = new HashMap<>();
    // 把订阅者当作key,事件当作value,当我们注册和注销的时候会用的到
    typesBySubscriber = new HashMap<>();
    // 维护者粘性事件
    stickyEvents = new ConcurrentHashMap<>();

    // 接下来就是EventBus中非常重要的三个Poster(同时队形这个threadMode)负责线程之间的调度
    mainThreadSupport = builder.getMainThreadSupport();
    mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
    backgroundPoster = new BackgroundPoster(this);
    asyncPoster = new AsyncPoster(this);

    // 表示Event生成的索引值
    indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
    // 这个很重要,是订阅者方法的查找器(也就是说带有注解的方法)
    subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
            builder.strictMethodVerification, builder.ignoreGeneratedIndex);

    // 这之后就是一些日志,异常的一些标志位
    logSubscriberExceptions = builder.logSubscriberExceptions;
    logNoSubscriberMessages = builder.logNoSubscriberMessages;
    sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
    sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
    throwSubscriberException = builder.throwSubscriberException;

    // 事件继承标志位(事件继承是否要发送后面会介绍)
    eventInheritance = builder.eventInheritance;
    // 线程池
    executorService = builder.executorService;
}

小结:这里用的是构建者模式创建的实例,下面会对其中的poster有介绍

mainThreadPoster

// 调用HandlerPoster实例化
@Override
public Poster createPoster(EventBus eventBus) {
    return new HandlerPoster(eventBus, looper, 10);
}

这是我们研究的重点

// 很明显,底层是通过handler来实现的(Poster 就是一个实现入队的接口方法)
public class HandlerPoster extends Handler implements Poster {

// 底层就是实现一个队列(存放事件)
private final PendingPostQueue queue;
// 事件在handler的handlerMessage存在的最大事件值
private final int maxMillisInsideHandleMessage;
private final EventBus eventBus;
// 标志handler是否运行起来
private boolean handlerActive;

// 初始化
protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
    super(looper);
    this.eventBus = eventBus;
    this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
    queue = new PendingPostQueue();
}
// 事件入队列
public void enqueue(Subscription subscription, Object event) {
    // PendingPost就不再列举,就是通过ArrayList获取和释放
    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
    synchronized (this) {
        queue.enqueue(pendingPost);
        if (!handlerActive) {
            handlerActive = true;
            if (!sendMessage(obtainMessage())) {
                throw new EventBusException("Could not send handler message");
            }
        }
    }
}

// 主要的核心方法
@Override
public void handleMessage(Message msg) {
    boolean rescheduled = false;
    try {
        long started = SystemClock.uptimeMillis();
        // 开启循环,获取事件调用invokeSubscriber分发处理事件
        while (true) {
            PendingPost pendingPost = queue.poll();
            if (pendingPost == null) {
                synchronized (this) {
                    // Check again, this time in synchronized
                    pendingPost = queue.poll();
                    // 处理完毕,则handlerActive置为false,结束
                    if (pendingPost == null) {
                        handlerActive = false;
                        return;
                    }
                }
            }
            eventBus.invokeSubscriber(pendingPost);
            long timeInMethod = SystemClock.uptimeMillis() - started;
            // 用到了最大事件值,判断是否在最大事件值之内(不可能无限制处理分发事件,注意和下面分析的区别)
            if (timeInMethod >= maxMillisInsideHandleMessage) {
                if (!sendMessage(obtainMessage())) {
                    throw new EventBusException("Could not send handler message");
                }
                rescheduled = true;
                return;
            }
        }
    } finally {
        handlerActive = rescheduled;
    }
}
}

小结:就是通过handler,在handMessage中开启循环获取分发处理事件

backgroundPoster

// 很明显,实现入队列方法,我们要把主要目光放在实现的run方法之中
final class BackgroundPoster implements Runnable, Poster {

// 同样的队列(和mainThreadPoster是一致的)
private final PendingPostQueue queue;
private final EventBus eventBus;

private volatile boolean executorRunning;

// 初始化,获取需要的eventBus
BackgroundPoster(EventBus eventBus) {
    this.eventBus = eventBus;
    queue = new PendingPostQueue();
}
// 入队操作
public void enqueue(Subscription subscription, Object event) {
    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
    synchronized (this) {
        queue.enqueue(pendingPost);
        if (!executorRunning) {
            executorRunning = true;
            // 通过线程池执行操作(我们要接下来关注run方法)
            eventBus.getExecutorService().execute(this);
        }
    }
}

// 同样是取出,循环取完为止(是放在线程池中执行的)
@Override
public void run() {
    try {
        try {
            while (true) {
                PendingPost pendingPost = queue.poll(1000);
                if (pendingPost == null) {
                    synchronized (this) {
                        // Check again, this time in synchronized
                        pendingPost = queue.poll();
                        if (pendingPost == null) {
                            executorRunning = false;
                            return;
                        }
                    }
                }
                eventBus.invokeSubscriber(pendingPost);
            }
        } catch (InterruptedException e) {
            eventBus.getLogger().log(Level.WARNING, Thread.currentThread().getName() + " was interruppted", e);
        }
    } finally {
        executorRunning = false;
    }
}

}

小结:通过线程池,循环取出事件执行,取完为止,同样调用invokeSubscriber方法分发处理事件(这个方法接下来我会介绍)

asyncPoster

class AsyncPoster implements Runnable, Poster {

private final PendingPostQueue queue;
private final EventBus eventBus;

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

public void enqueue(Subscription subscription, Object event) {
    PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
    queue.enqueue(pendingPost);
    // 也是通过线程池
    eventBus.getExecutorService().execute(this);
}

// 注意,虽然都是通过线程池处理,但是这是处理一个事件,进行分发处理
@Override
public void run() {
    PendingPost pendingPost = queue.poll();
    if(pendingPost == null) {
        throw new IllegalStateException("No pending post available");
    }
    eventBus.invokeSubscriber(pendingPost);
}

}

小结: 通过线程池分发处理一个事件

总结:这次的getDefault方法,最终要的就是三个Poster,他们线程调度处理后面会用到,主要明白其中三个Poster大概流程,构建者模式构建了哪几个中重要的变量即可。(后面的说明会用的到此处提到的重要变量和方法。

你可能感兴趣的:(EventBus(二getDefault()))