这种表关系是event和subsciption的对应关系,比如在Android中多个activity可能会注册监听同一个event事件,所以在执行:
EventBus.getDefault().post(new Event1());
的时候所有注册监听了Event1的监听都会要会收到回调,看下subsciption的结构
subsciption中包含,订阅的事件和订阅者本身,上面中所有的event就是订阅的事件,在Android中订阅的事件代码如下:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(Event event) {
}
而subsriber就是订阅者比如会在activity的onstart中执行
…
EventBus.getDefault().register(this);
那么subsribe就是activity。
思考 为什么需要保存Event和subsribe对应的关系表?
这是因为一个Event可能会有被多个subsribe订阅,所以有当执行post(Event)的时候会查找到所有订阅了Event事件的subscribe并调用其中的event方法。下面看下post方法:
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList subscriptions;
synchronized (this) {
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
postToSubscription(subscription, event, postingState.isMainThread);
aborted = postingState.canceled;
} finally {
postingState.event = null;
postingState.subscription = null;
postingState.canceled = false;
}
if (aborted) {
break;
}
}
return true;
}
return false;
}
}
post和postSticky主要都会调用到上面的方法,上面方法中subscriptionsByEventType.get(eventClass)
就是通过event的类型找上面的表中找到对应的subscriptions进行通知的。
第三幅图
在看第三幅图之前思考一个问题,postSticky到底是怎么执行的?为什么先执行postSticky,后执行register还是可以监听到event事件? 先看postSticky代码:
public void postSticky(Object event) {
synchronized (stickyEvents) {
stickyEvents.put(event.getClass(), event);
}
// Should be posted after it is putted, in case the subscriber wants to remove immediately
post(event);
}
复制代码
原来执行postSticky的时候会将event.getclass和event保存起来,然后再看下subscribe代码:
if (subscriberMethod.sticky) {
if (eventInheritance) {
// Existing sticky events of all subclasses of eventType have to be considered.
// Note: Iterating over all events may be inefficient with lots of sticky events,
// thus data structure should be changed to allow a more efficient lookup
// (e.g. an additional map storing sub classes of super classes: Class -> List).
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet(); for (Map.Entry
先判断注册监听的event是不是sticky的如果是就会用stickEvents表中找到stickyEvent如果如果注册的事件event和stickyEvent一样那么就会执行一次postToSubscription方法,也就是调用注册的方法执行。
总结
1、要理解EventBus就要从register,unRegister,post,postSticky方法入手。要理解register实质上是将订阅对象(比如activity)中的每个带有subscriber的方法找出来,最后获得调用的就是这些方法。订阅对象(比如activity)是一组event方法的持有者。
2、后注册的对象中sticky方法能够收到之前的stickyEvent方法的原因是EventBus中维护了stickyEvent的hashMap表,在subsribe注册的时候就遍历其中有没有注册监听stickyEvent如果有就会执行一次回调。
EventBus缺点
1、使用的时候有定义很多event类
2、event在注册的时候会调用反射去遍历注册对象的方法在其中找出带有@subscriber标签的方法,性能不高。
3、需要自己注册和反注册,如果忘了反注册就会导致内存泄漏
推荐阅读:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
总结
Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!
上面分享的字节跳动公司2021年的面试真题解析大全,笔者还把一线互联网企业主流面试技术要点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
【Android高级架构视频学习资源】
Android部分精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**