2023年7月24日发(作者:)
征服⾯试官:RxJava原理篇掌握这篇⾯试题汇总,吊打⾯试官!1、RxJava 如何实现线程切换?subscribeOn 是通过新建
Observable 的⽅式,使⽤
OnSubscribe 类的⽅式去做到线程切换的。observeOn 是通过
operator 操作符的形式去完成线程切换的,所以他的作⽤域和其他操作符⼀样,是调⽤
observeOn 之后的链路。() 代表 io 操作的线程, 通常⽤于⽹络,读写⽂件等 io 密集型的操作ation() 代表 CPU 计算密集型的操作, 例如需要⼤量计算的操作ead() 代表⼀个常规的新线程read() 代表 Android 的主线程⽣产者线程调度流程概括1.
()等价于
new IoScheduler()。2.
new IoScheduler() Rxjava 创建了线程池,为后续创建线程做准备,同时创建并运⾏了⼀个清理线程
RxCachedWorkerPoolEvictor,定期执⾏清理任务。3.
subscribeOn()返回⼀个
ObservableSubscribeOn 对象,它是
Observable 的⼀个装饰类,增加了
scheduler。4. 调⽤
subscribe()⽅法,在这个⽅法调⽤后,subscribeActual() 被调⽤,才真正执⾏了IoSchduler 中的
createWorker() 创建线程并运⾏,最终将上游
Observable 的
subscribe() ⽅法调度到新创建的线程中运⾏。消费者线程调度流程概括1.
read()先创建⼀个包含
handler 的
Scheduler, 这个
handler 是主线程的
handler。2.
observeOn ⽅法创建
ObservableObserveOn,它是上游
Observable 的⼀个装饰类,其中包含前⾯创建的
Scheduler 和
bufferSize 等.3. 当订阅⽅法
subscribe 被调⽤后,ObservableObserveOn 的
subscribeActual ⽅法创建 并调⽤上游的
subscribe ⽅法,同时将⾃⾝接收的参数’observer’⽤装饰类
ObserveOnObserver 装饰后传递给上游。4. 当上游调⽤被
ObserveOnObserver 的
onNext、onError 和
onComplete ⽅法时,ObserveOnObserver 将上游发送的事件通通加⼊到队列
queue 中,然后再调⽤
scheduler将处理事件的⽅法调度到对应的线程中(本例会调度到 main thread)。 处理事件的⽅法将queue 中保存的事件取出来,调⽤下游原始的
observer 再发射出去。5. 经过以上流程,下游处理事件的消费者线程就运⾏在了
observeOn 调度后的
thread 中。总结Schedulers 内部封装了各种
Scheduler。每⼀个
Scheduler 中都封装的有线程池,⽤于执⾏后台任务。Scheduler 是所有调度器实现的抽象⽗类,⼦类可以通过复写其
scheduleDirect() 来⾃⾏决定如何调度被分配到的任务;同时通过复写其createWorker() 返回的
实例来执⾏具体的某个任务。此处的任务指的是通过
Runnable 封装的可执⾏代码块。1. ⼦线程切换主线程:给主线程所在的Handler发消息,然后就把逻辑切换过去了。2. 主线程切换⼦线程:把任务放到线程池中执⾏就能把执⾏逻辑切换到⼦线程3. ⼦线程切换⼦线程:把任务分别扔进两个线程就⾏了。Rxjava 的
subscribe ⽅法是由下游⼀步步向上游进⾏传递的。会调⽤上游的
subscribe,直到调⽤到事件源。2、RxJava 有哪些操作符?创建操作符转换操作符过滤操作符条件操作符延时操作符其他操作符map 转换事件,返回普通事件flatMap 转换事件,返回` ObservableconactMap concatMap 与 FlatMap 的唯⼀区别就是 concatMap 保证了顺序subscribeOn 规定被观察者所在的线程observeOn 规定下⾯要执⾏的消费者所在的线程take 接受⼀个 long 型参数 count ,代表⾄多接收 count 个数据debounce 去除发送频率过快的项,常⽤在重复点击解决上,配合 RxBinging 使⽤效果很好timer 定时任务,多少时间以后发送事件interval 每隔⼀定时间执⾏⼀些任务skip 跳过前多少个事件distinct 去重takeUntil 直到到⼀定条件的是停下,也可以接受另外⼀个被观察者,当这个被观察者结束之后则停⽌第⼀个被观察者Zip 专⽤于合并事件,该合并不是连接(连接操作符后⾯会说),⽽是两两配对,也就意味着,最终配对出的 Observable 发射事件数⽬只和少的那个相同。不影响Observable的发射,Observable 被观察者会⼀直发射,不会停,只是Observer 接收不到merge 多个 Observable 发射的数据随机发射,不保证先后顺序Concat 多个 Observable 组合以后按照顺序发射,保证了先后顺序,不过最多能组合4个 Observable ,多的可以使⽤contactArrayonErrorReturn 遇到错误是发射指定的数据到 onNext,并正常终⽌onErrorResumeReturn 遇到错误时,发射设置好的⼀个 Observable ,⽤来发送数据到 onNext,并正常终⽌onExceptionResumeReturn 和onErrorResumeReturn 类似,不同之处在于会判断是否是 Exception。如果是和onErrorResumeReturn ⼀样,不是则会调⽤ onError。不会调⽤onNext3、操作符 map 和 flatmap 的区别?map:【数据类型转换】将被观察者发送的事件转换为另⼀种类型的事件。flatMap:【化解循环嵌套和接⼝嵌套】将被观察者发送的事件序列进⾏拆分 & 转换 后合并成⼀个新的事件序列,最后再进⾏发送。concatMap:【有序】与 flatMap 的 区别在于,拆分 & 重新合并⽣成的事件序列 的顺序与被观察者旧序列⽣产的顺序⼀致。共同点1. 都是依赖 Function 函数进⾏转换(将⼀个类型依据程序逻辑转换成另⼀种类型,根据⼊参和返回值)2. 都能在转换后直接被 subscribe区别1. 返回结果不同map 返回的是结果集,flatmap 返回的是包含结果集的 Observable 对象(返回结果不同)2. 执⾏顺序不同map 被订阅时每传递⼀个事件执⾏⼀次 onNext ⽅法,flatmap 多⽤于多对多,⼀对多,再被转化为多个时,⼀般利⽤ from/just进⾏⼀⼀分发,被订阅时将所有数据传递完毕汇总到⼀个 Observable 然后⼀⼀执⾏ onNext ⽅法。(如单纯⽤于⼀对⼀转换则和map 相同)3. 转换对象的能⼒不同map 只能单⼀转换,单⼀指的是只能⼀对⼀进⾏转换,指⼀个对象可以转化为另⼀个对象但是不能转换成对象数组。flatmap 既可以单⼀转换也可以⼀对多/多对多转换,flatmap 要求返回 Observable,因此可以再内部进⾏事件分发,逐个取出单⼀对象。4、RxJava 如何解决内存泄漏?1. 订阅的时候拿到
Disposable ,主动调⽤
dispose2. 使⽤
RxLifeCycle3. 使⽤
AutoDispose5、RxJava 中 Observable、Flowable、Single、Maybe、Completable 使⽤时如何选择?在
RxJava2 ⾥⾯,Observable、Flowable、Single、Maybe、Completable 这⼏个在使⽤起来区别不⼤,因为他们都可以⽤⼀个或多个函数式接⼝作为参数进⾏订阅(subscribe),需要⼏个传⼏个就可以了。但是从各个的设计初衷来讲,个⼈感觉最适⽤于⽹络请求这种情况的是
Single 和
Completable。⽹络请求是⼀个
Request 对应⼀个
Response,不会出现背压情况,所以不考虑
Flowable;⽹络请求是⼀个
Request 对应⼀个
Response,不是⼀个连续的事件流,所以在
onNext 被调⽤之后,onComplete 就会被马上调⽤,所以只需要
onNext 和
onComplete 其中⼀个就够了,不考虑
Observable、Maybe ;对于关⼼
ResponseBody 的情况,Single 适⽤;对于不关⼼
ResponseBody 的情况,Completable 适⽤。6、为什么 subscribeOn() 只有第⼀次切换有效因为 RxJava 最终能影响
ObservableOnSubscribe 这个匿名实现接⼝的运⾏环境的只能是最后⼀次运⾏的
subscribeOn() ,⼜因为 RxJava订阅的时候是从下往上订阅,所以从上往下第⼀个
subscribeOn() 就是最后运⾏的,这就造成了写多个
subscribeOn() 并没有什么乱⽤的现象。
发布者:admin,转转请注明出处:http://www.yc00.com/news/1690214259a315902.html
评论列表(0条)