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

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) {

int size = subscriptions.size();

for (int i = 0; i < size; i++) {

Subscription subscription = subscriptions.get(i);

if (subscription.subscriber == subscriber) {

subscription.active = false;

subscriptions.remove(i);

i–;

size–;

}

}

}

}

unregister流程:

1.传进来需要取消的订阅者

2.遍历获得该订阅者的所有事件

3.使用unsubscribeByEventType去遍历事件,看看哪些订阅者都有这个事件,然后从集合删除订阅者,订阅者不再和事件有关联

面试复习路线,梳理知识,提升储备

自己的知识准备得怎么样,这直接决定了你能否顺利通过一面和二面,所以在面试前来一个知识梳理,看需不需要提升自己的知识储备是很有必要的。

关于知识梳理,这里再分享一下我面试这段时间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)

  • 架构师筑基必备技能
  • Android高级UI与FrameWork源码
  • 360°全方面性能调优
  • 解读开源框架设计思想
  • NDK模块开发
  • 微信小程序
  • Hybrid 开发与Flutter

知识梳理完之后,就需要进行查漏补缺,所以针对这些知识点,我手头上也准备了不少的电子书和笔记,这些笔记将各个知识点进行了完美的总结:

Android开发七大模块核心知识笔记

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?

1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
过前两轮技术面试的几率。

如何使用它?

1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

[外链图片转存中…(img-61g51pZA-1715358281147)]

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值