EventBus 中的一些设计
1. 事件的包装
1.1 在编译时注解阶段包装被@Subscriber 修饰的方法
putIndex(new SimpleSubscriberInfo(com.study.sangerzhong.studyapp.ui.MainActivity.class, true, new SubscriberMethodInfo[] {
new SubscriberMethodInfo("onEvent", com.study.sangerzhong.studyapp.ui.MainActivity.DriverEvent.class, ThreadMode.POSTING, 0, false),
// 类中每一个被Subscribe标识的方法都在这里添加进来
}));
通过解析注解获得方法的方法名等信息保存起来
1.2 获取方法的信息
- 获取到 自动生成的索引类
// 需要自己手动添加
EventBus mEventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();
2. PostingThreadState 的设计
private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {
@Override
protected PostingThreadState initialValue() {
return new PostingThreadState();
}
};
// PostingThreadState 的内部结构
final static class PostingThreadState {
final List<Object> eventQueue = new ArrayList<>(); // 事件队列
boolean isPosting;
boolean isMainThread;
Subscription subscription;
Object event;
boolean canceled;
}
每一个不同线程在调用POST 的时候,会给每一个线程初始化一个PostingThreadState,来保存该线程发送事件的缓存
3. FindState 和 PendingPost —– 对象池的设计
private static final int POOL_SIZE = 4;
private static final FindState[] FIND_STATE_POOL = new FindState[POOL_SIZE];
// 使用的时候从池子里面拿
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
FindState state = FIND_STATE_POOL[i];
if (state != null) {
FIND_STATE_POOL[i] = null;
return state;
}
}
}
// 使用完返回池子
synchronized (FIND_STATE_POOL) { // 把 findState放回池子里面
for (int i = 0; i < POOL_SIZE; i++) {
if (FIND_STATE_POOL[i] == null) {
FIND_STATE_POOL[i] = findState;
break;
}
}
}
PendingPost 的设计
final class PendingPostQueue {
// 头指针
private PendingPost head;
// 尾指针
private PendingPost tail;
synchronized void enqueue(PendingPost pendingPost) {
if (pendingPost == null) {
throw new NullPointerException("null cannot be enqueued");
}
if (tail != null) {
// 为指针向后面移动一个
tail.next = pendingPost;
tail = pendingPost;
} else if (head == null) {
head = tail = pendingPost;
} else {
throw new IllegalStateException("Head present, but no tail");
}
notifyAll();
}
synchronized PendingPost poll() {
PendingPost pendingPost = head;
if (head != null) {
head = head.next;
if (head == null) {
tail = null;
}
}
return pendingPost;
}
synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException {
if (head == null) {
wait(maxMillisToWait);
}
return poll();
}
}
final class PendingPost {
// 对象池的设计
private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();
Object event;
Subscription subscription;
PendingPost next;
private PendingPost(Object event, Subscription subscription) {
this.event = event;
this.subscription = subscription;
}
static PendingPost obtainPendingPost(Subscription subscription, Object event) {
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);
}
static void releasePendingPost(PendingPost pendingPost) {
// 将对象放回池子
pendingPost.event = null;
pendingPost.subscription = null;
pendingPost.next = null;
synchronized (pendingPostPool) {
// Don't let the pool grow indefinitely
if (pendingPostPool.size() < 10000) {
pendingPostPool.add(pendingPost);
}
}
}
}
3 . 异常的处理
public final class SubscriberExceptionEvent {
/** The {@link EventBus} instance to with the original event was posted to. */
public final EventBus eventBus;
/** The Throwable thrown by a subscriber. */
public final Throwable throwable;
/** The original event that could not be delivered to any subscriber. */
public final Object causingEvent;
/** The subscriber that threw the Throwable. */
public final Object causingSubscriber;
public SubscriberExceptionEvent(EventBus eventBus, Throwable throwable, Object causingEvent,
Object causingSubscriber) {
this.eventBus = eventBus;
this.throwable = throwable;
this.causingEvent = causingEvent;
this.causingSubscriber = causingSubscriber;
}
}
异常的抛出,在invoke方法的时候
void invokeSubscriber(Subscription subscription, Object event) {
try {
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
} catch (InvocationTargetException e) {
// 处理异常
handleSubscriberException(subscription, event, e.getCause());
} catch (IllegalAccessException e) {
throw new IllegalStateException("Unexpected exception", e);
}
}
/* 对不同类型的异常做不同的处理 */
private void handleSubscriberException(Subscription subscription, Object event, Throwable cause) {
if (event instanceof SubscriberExceptionEvent) {
if (logSubscriberExceptions) {
// Don't send another SubscriberExceptionEvent to avoid infinite event recursion, just log
logger.log(Level.SEVERE, "SubscriberExceptionEvent subscriber " + subscription.subscriber.getClass()
+ " threw an exception", cause);
SubscriberExceptionEvent exEvent = (SubscriberExceptionEvent) event;
logger.log(Level.SEVERE, "Initial event " + exEvent.causingEvent + " caused exception in "
+ exEvent.causingSubscriber, exEvent.throwable);
}
} else {
if (throwSubscriberException) {
throw new EventBusException("Invoking subscriber failed", cause);
}
if (logSubscriberExceptions) {
logger.log(Level.SEVERE, "Could not dispatch event: " + event.getClass() + " to subscribing class "
+ subscription.subscriber.getClass(), cause);
}
if (sendSubscriberExceptionEvent) {
SubscriberExceptionEvent exEvent = new SubscriberExceptionEvent(this, cause, event,
subscription.subscriber);
/*发送异常*/
post(exEvent);
}
}
}
订阅异常
@Subscribe(threadMode = ThreadMode.MAIN)
public void handleFailureEvent(ThrowableFailureEvent event) {
// do something
}