老司机狂飙之路--EventBus原理简要分析(2)

二、实战篇

步入正题;先来个整体的玩意

订阅者和事件的发布所在线程不固定,取决于ThreadMode,但是每个线程都有相关联的Queue。

首先从注册开始看,

EventBus.getDefault().register(this)

咱先看getDefault()里面有什么,如下

/** Convenience singleton for apps using a process-wide EventBus instance. */

public static EventBus getDefault() {

if (defaultInstance == null) {

synchronized (EventBus.class) {

if (defaultInstance == null) {

defaultInstance = new EventBus();

}

}

}

return defaultInstance;

}

再深入看new EventBus做了啥?咦?等等,上面的不是双重锁机制吗,https://blog.csdn.net/qq_27489007/article/details/84966680

/**

  • Creates a new EventBus instance; each instance is a separate scope in which events are delivered. To use a central bus, consider {@link #getDefault()}.

*/

public EventBus() {

this(DEFAULT_BUILDER);

}

传进去个变量?去瞅瞅 ,在这个过程中建造者模式蹦出来了,你有没有发现?

private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();

发现各种初始化在构造中使用builder实现,回头看咱们上篇文章创建索引的时候使用

EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();

还是用buidler,异曲同工啊;继续代码点点点,深入深入,分析出流程:

1.注册者和事件消费是1:N的关系,一个Event与注册者也是1:N的关系,即register(this)对比当前的消费事件是1:N,post()对比register也是1:N

2.注册的不可再注册

说完注册,我们再说一说那事件分发,我们先从post入手;

/** Posts the given event to the event bus. */

public void post(Object event) {

//1.获取当前线程postingstate

PostingThreadState postingState = currentPostingThreadState.get();

//2.获取线程的事件队列

List eventQueue = postingState.eventQueue;

//3.等待分发

eventQueue.add(event);

if (!postingState.isPosting) {

//判断是否主线程

postingState.isMainThread = isMainThread();

postingState.isPosting = true;

if (postingState.canceled) {

throw new EventBusException(“Internal error. Abort state was not reset”);

}

try {

while (!eventQueue.isEmpty()) {

postSingleEvent(eventQueue.remove(0), postingState);

}

} finally {

postingState.isPosting = false;

postingState.isMainThread = false;

}

}

}

那啥是PostingThreadState,他包含了当前事件队列,以及订阅者订阅事件等信息,拿到这些就可以去实现分发啦;可我明明看见上面使用的postSingleEvent呀,这有什么联系?我们进去瞅瞅

private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {

Class<?> eventClass = event.getClass();

boolean subscriptionFound = false;

if (eventInheritance) {

List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);

int countTypes = eventTypes.size();

for (int h = 0; h < countTypes; h++) {

Class<?> clazz = eventTypes.get(h);

subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);

}

} else {

subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);

}

if (!subscriptionFound) {

if (logNoSubscriberMessages) {

logger.log(Level.FINE, "No subscribers registered for event " + eventClass);

}

if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&

eventClass != SubscriberExceptionEvent.class) {

post(new NoSubscriberEvent(this, event));

}

}

}

发现又多了个postSingleEventForEventType() ,再深入,发现是 postToSubscription(),而这里面又是 invokeSubscriber();至此结束我们捋一捋:

这次该轮到取消注册unregister,这个代码少一些,直白一点如下:

/** Unregisters the given subscriber from all event classes. */

public synchronized void unregister(Object subscriber) {

List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);

if (subscribedTypes != null) {

for (Class<?> eventType : subscribedTypes) {

unsubscribeByEventType(subscriber, eventType);

}

typesBySubscriber.remove(subscriber);

} else {

logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());

}

}

/** Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber. */

private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {

List subscriptions = subscriptionsByEventType.get(eventType);

if (subscriptions != null) {

学习分享

在当下这个信息共享的时代,很多资源都可以在网络上找到,只取决于你愿不愿意找或是找的方法对不对了

很多朋友不是没有资料,大多都是有几十上百个G,但是杂乱无章,不知道怎么看从哪看起,甚至是看后就忘

如果大家觉得自己在网上找的资料非常杂乱、不成体系的话,我也分享一套给大家,比较系统,我平常自己也会经常研读。

2021最新上万页的大厂面试真题

image

七大模块学习资料:如NDK模块开发、Android框架体系架构…

image

2021大厂面试真题:

image

只有系统,有方向的学习,才能在短时间内迅速提高自己的技术,只有不断地学习,不懈的努力才能拥有更好的技术,才能在互联网行业中立于不败之地。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
**

[外链图片转存中…(img-YPv0yGf5-1715358315933)]

七大模块学习资料:如NDK模块开发、Android框架体系架构…

[外链图片转存中…(img-dR3lEMCl-1715358315934)]

2021大厂面试真题:

[外链图片转存中…(img-phAkvx16-1715358315934)]

只有系统,有方向的学习,才能在短时间内迅速提高自己的技术,只有不断地学习,不懈的努力才能拥有更好的技术,才能在互联网行业中立于不败之地。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值