RxJava和EventBus的区别
发布时间:2025-05-22 19:07:52 发布人:远客网络
一、RxJava和EventBus的区别
1、RxJava要比EventBus的应用更广泛,EventBus仅仅是作为一种消息的传递工具,但是RxJava里面几乎可以做任何事情。
2、如果是Android开发的话,可以使用RxAndroid,这是对RxJava的一个扩展,结合sqare公司的retrofit可以很轻松的完成网络的访问。
3、我们知道,在Android中异步操作一般使用AsycTask来完成,但是AsycTask有很多缺点,如不能方便的终止任务的执行等。
4、RxAndroid完全可以替代AsycTask来完成各种异步操作,而且还有BindActivity和BindFragment方法,你根本不需要考虑异步操作时的Activity和Fragment的生命周期问题,还有更加强大的的链式调用,可以使程序很简洁。
5、EventBus有个缺点就是凡是使用了EventBus的类都不能进行混淆了,否则Evnetbus就找不到OnEvent方法了。
二、javaeventbus注入失败
1、缺少必要的依赖库或未正确初始化。
2、javaeventbus注入失败通常是缺少必要的依赖库或未正确初始化导致的,可以尝试检查依赖库是否正确引入,并且与JavaEventBus版本匹配,也要确保JavaEventBus已正确初始化,并且事件监听器已正确注册。
3、JavaEventBus是一款Java语言编写的事件总线库,用于实现组件之间的松耦合通信。
三、为什么避免使用EventBus/RxBus
1、EventBus和Otto在之前作为Android组件间通信工具,简单方便十分受欢迎,但是也非常容易Abuse。大概有如下几个缺点:
2、由于是Event,在发布Event的时候就要做好准备可能并没有人接受这个Event, Subscribe的时候也要做好准备可能永远不会收到Event。Event无论顺序还是时间上都某种程度上不太可控。如果你将数据寄托在Event上然后就直接在Android其他生命周期方法中直接使用这个数据或成员变量。那么很有可能你会得到NPE。
3、EventBus看似将你的程序解耦,但是又有些过了。我们常常使用EventBus传数据,这已经是Dependency级别的数据而不是一个可以被解耦出来的模块。这样就造成了过多EventBus的代码会造成代码结构混乱,难以测试和追踪,违背了解耦的初衷。这时如果有意或无意的造成了Nested Event。那情况会更糟。
4、由于EventBus的种种缺点,以及后面RxJava的出现。很多人都开始使用RxJava来取代EventBus。甚至Otto的官方介绍里都写到:
5、This project is deprecated in favor of RxJava and
6、RxAndroid. These projects permit the same event-driven
7、programming model as Otto, but they’re more capable and offer better control of threading.
8、If you’re looking for guidance on migrating from Otto to Rx, this post
9、链接是一个教你怎么使用RxJava来自己手动写一个RxBus来代替EventBus的文章。虽然看起来是在用RxJava。但是实际上却仍然在用EventBus。甚至这个封装其实也并没有GreenRobot或者Otto来的好。
10、我们看看Jake Wharton对RxBus的评价:
11、我想"RxBus"唯一的好处就是他是一个Rx的入门毒品。否则的话,你要么就不是在用Rx,要么你需要更加惯用的Rx资源(渣翻译见谅)
12、subscribeActual部分我们先不考虑。然而Jake指出最好不要使用Relay来“重新发明”Event Bus.
13、Jake Wharton在GOTO 2016上的讲座中提到,我们正常的Android编程是这样的:
14、而使用RxJava。我们的结构,更像这样
15、我们使用RxJava来直接把组件相连,对所接受到的数据作出反应,所谓的"Reactive"。
16、而使用Eventbus? Jake没说,我自己画一个:
17、我们作为一个中间人,传递消息。EventBus作为另一个中间人。帮我们传递消息。(这也就是所谓的“看似解耦”)
18、再打个比方,虽然我们将EventBus翻译成时间总线,但是其实总线就是Bus也就是公交车。而RxJava更像一个专车,Uber或者滴滴。他直接链接你的两个或多个需要通信的类。传输数据,当然你可以做一个很大的专车,穿梭在所有类之间,也就是所谓的RxBus。所以在这里为什么放弃RxBus也就不言而喻了不是?
19、怎样才是正确(正常?)的RxJava使用方式?
20、其实Jake也在GitHub的讨论上给出了一个答案:
21、所以应该是,每当你想发布一个Event在EventBus时,直接暴露一个Observable出来。每当你想接受一个Event时,找到这个Observable并且Subscribe他。
22、目标和地点都很明确。你的Subscriber明确的知道他Subscribe的是谁,而且明确的知道我需要作出什么反应。这也正是RxJava的核心“响应式编程”。
23、由于使用了Observable,对于异常处理将会非常方便。而且还有功能强大全面的Operator来辅助你。
24、虽然看起来耦合性有所增加。但是这是必要的,上面也说过,EventBus虽然在代码上看似解耦。其实他们还是联系在一起的。而我们这样直接暴露Observable给需要的其他类,这完成了1-> 1/N的链接,而不需要EventBus这个中间人来传递消息/事件,而且保证我们需要的事件一定会直接到达。
25、上下两个Fragment,上面的一个EditText,下面的一个TextView。上面的EditText变化的时候下面的TextView也跟着变化。
26、先把EditText的TextChangedListener封装在Observable里:
27、 public void beforeTextChanged(CharSequence s, int start, int count, int after){
28、 public void onTextChanged(CharSequence s, int start, int before, int count){
29、 public void afterTextChanged(Editable s){
30、 public Observable<String> getEditTextObservable(){
31、不习惯自己封装可以使用RxBinding:
32、.map(event-> event.text().toString());
33、再从我们的TextViewFragment中取到这个封装好的Observable:
34、 FragmentEditText fragment=(FragmentEditText) getFragmentManager().findFragmentByTag(FragmentEditText.TAG);
35、 fragment.getStringObservable().subscribe(s-> textView.setText(s));
36、由于我们将editText封装在Observable里,无论是create()方法还是使用RxBinding,都会持有这个View的强引用。造成内存泄漏。所以我们一定要在最后加入dispose()方法来释放。所以我推荐使用RxBinding,他已经帮我们在dispose()方法里写好了解除Listener的方法。
37、因为并没有使用publish操作符,导致多个Subscriber的时候还是有些许问题。可以考虑直接加入.share().