先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
正文
2.1 EventBus 切换线程
EventBus 是一个基于观察者模式的事件订阅/发布框架。利用 EventBus 可以在不同模块之间,实现低耦合的消息通信。
EventBus 诞生以来这么多年,在很多生产项目中都可以看到它的身影。而从更新日志可以看到,除了体积小,它还很稳定,这两年就没更新过,最后一次更新也只是因为支持所有的 JVM,让其使用范围不仅仅局限在 Android 上。
可谓是非常的稳定,稳定到让人有一种感觉,要是你使用 EventBus 出现了什么问题,那一定是你使用的方式不对。
EventBus 的使用方式,对于 Android 老司机来说,必然是不陌生的,相关资料太多,这里就不再赘述了。
在 Android 下,线程的切换是一个很常用而且很必须的操作,EventBus 除了可以订阅和发送消息之外,它还可以指定接受消息处理消息的线程。
也就是说,无论你 post()
消息时处在什么线程中,EventBus 都可以将消息分发到你指定的线程上去,听上去就感觉非常的方便。
不过无论怎么切换,无外乎几种情况:
- UI 线程切子线程。
- 子线程切 UI 线程。
- 子线程切其他子线程。
在我们使用 EventBus 注册消息的时候,可以通过 @Subscribe
注解来完成注册事件, @Subscribe
中可以通过参数 threadMode
来指定使用那个线程来接收消息。
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventTest(event:TestEvent){
// 处理事件
}
threadMode
是一个 enum,有多种模式可供选择:
- POSTING,默认值,那个线程发就是那个线程收。
- MAIN,切换至主线程接收事件。
- MAIN_ORDERED,v3.1.1 中新增的属性,也是切换至主线程接收事件,但是和 MAIN 有些许区别,后面详细讲。
- BACKGROUND,确保在子线程中接收事件。细节就是,如果是主线程发送的消息,会切换到子线程接收,而如果事件本身就是由子线程发出,会直接使用发送事件消息的线程处理消息。
- ASYNC,确保在子线程中接收事件,但是和 BACKGROUND 的区别在于,它不会区分发送线程是否是子线程,而是每次都在不同的线程中接收事件。
EventBus 的线程切换,主要涉及的方法就是 EventBus 的 postToSubscription()
方法。
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
case POSTING:
invokeSubscriber(subscription, event);
break;
case MAIN:
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
mainThreadPoster.enqueue(subscription, event);
}
break;
case MAIN_ORDERED:
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
// temporary: technically not correct as poster not decoupled from subscriber
invokeSubscriber(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
可以看到,在 postToSubscription()
方法中,对我们配置的 threadMode 值进行了处理。
这端代码逻辑非常的简单,接下来我们看看它们执行的细节。
2.2 切换至主线程接收事件
想在主线程接收消息,需要配置 threadMode 为 MAIN。
case MAIN:
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
mainThreadPoster.enqueue(subscription, event);
}
这一段的逻辑很清晰,判断是主线程就直接处理事件,如果是非主线程,就是用 mainThreadPoster 处理事件。
追踪 mainThreadPoster
的代码,具体的逻辑代码都在 HandlerPoster 类中,它实现了 Poster 接口,这就是一个普通的 Handler,只是它的 Looper 使用的是主线程的 「Main Looper」,可以将消息分发到主线程中。
为了提高效率,EventBus 在这里还做了一些小优化,值得我们借鉴学习。
为了避免频繁的向主线程 sendMessage()
,EventBus 的做法是在一个消息里尽可能多的处理更多的消息事件,所以使用了 while 循环,持续从消息队列 queue 中获取消息。
同时为了避免长期占有主线程,间隔 10ms (maxMillisInsideHandleMessage = 10ms)会重新发送 sendMessage()
,用于让出主线程的执行权,避免造成 UI 卡顿和 ANR。
MAIN
可以确保事件的接收,在主线程中,需要注意的是,如果事件就是在主线程中发送的,则使用 MAIN
会直接执行。为了让开发和可配置的成都更高,在 EventBus v3.1.1 新增了 MAIN_ORDERED
,它不会区分当前线程,而是通通使用 mainThreadPoster
来处理,也就是必然会走一遍 Handler 的消息分发。
当事件需要在主线程中处理的时候,要求不能执行耗时操作,这没什么好说的,另外对于 MAIN
或者 MAIN_ORDERED
的选择,就看具体的业务要求了。
2.3 切换至子线程执行
想要让消息在子线程中处理,可以配置 threadMode 为 BACKGROUND
或者 AYSNC
,他们都可以实现,但是也有一些区别。
先来看看 BACKGROUND
,通过 postToSubscription()
中的逻辑可以看到,BACKGROUND
会区分当前发生事件的线程,是否是主线程,非主线程这直接分发事件,如果是主线程,则 backgroundPoster
来分发事件。
case BACKGROUND:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
文末
不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊
小编将自己6年以来的面试经验和学习笔记都整理成了一个**937页的PDF,**以及我学习进阶过程中看过的一些优质视频教程。
其实看到身边很多朋友抱怨自己的工资很低,包括笔者也是一样的,其原因是在面试过程中没有给面试官一个很好的答案。所以笔者会持续更新面试过程中遇到的问题,也希望大家和笔者一起进步,一起学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ip204888 (备注Android)**
[外链图片转存中…(img-jLEEvIsq-1713357085000)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!