這一系列文章原本我發表在簡書。最近開始轉移到掘金。之後也會在掘金髮表(慢慢拋棄簡書了應該,掘金的技術環境確實比簡書好些)。javascript
EventBus和Otto在以前做爲Android組件間通訊工具,簡單方便十分受歡迎,可是也很是容易Abuse。大概有以下幾個缺點:java
因爲EventBus的種種缺點,以及後面RxJava的出現。不少人都開始使用RxJava來取代EventBus。甚至Otto的官方介紹裏都寫到:android
Deprecated!
This project is deprecated in favor of RxJava and
RxAndroid. These projects permit the same event-driven
programming model as Otto, but they’re more capable and offer better control of threading.gitIf you’re looking for guidance on migrating from Otto to Rx, this post
is a good start.github
連接是一個教你怎麼使用RxJava來本身手動寫一個RxBus來代替EventBus的文章。雖然看起來是在用RxJava。可是實際上卻仍然在用EventBus。甚至這個封裝其實也並無GreenRobot或者Otto來的好。
咱們看看Jake Wharton對RxBus的評價:
編程
再來一個GitHub的:
安全
subscribeActual部分咱們先不考慮。然而Jake指出最好不要使用Relay來「從新發明」Event Bus.app
這裏看圖說話:
Jake Wharton在GOTO 2016 上的講座中提到,咱們正常的Android編程是這樣的:
ide
再打個比方,雖然咱們將EventBus翻譯成時間總線,可是其實總線就是Bus也就是公交車。而RxJava更像一個專車,Uber或者滴滴。他直接連接你的兩個或多個須要通訊的類。傳輸數據,固然你能夠作一個很大的專車,穿梭在全部類之間,也就是所謂的RxBus。因此在這裏爲何放棄RxBus也就不言而喻了不是?工具
那麼,問題來了?
其實Jake 也在GitHub的討論上給出了一個答案:
因此應該是,每當你想發佈一個Event在EventBus時,直接暴露一個Observable出來。每當你想接受一個Event時,找到這個Observable而且Subscribe他。
這樣作的好處是什麼?
上下兩個Fragment,上面的一個EditText,下面的一個TextView。上面的EditText變化的時候下面的TextView也跟着變化。
先把EditText的TextChangedListener封裝在Observable裏:
stringObservable = Observable.create(e -> editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
e.onNext(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
}));
/** *** */
//Expose Observable
public Observable<String> getEditTextObservable() {
return stringObservable;
}複製代碼
不習慣本身封裝可使用RxBinding :
stringObservable = RxTextView.textChangeEvents(editText)
.map(event -> event.text().toString());複製代碼
再從咱們的TextViewFragment中 取到這個封裝好的Observable:
@Override
public void onStart() {
super.onStart();
FragmentEditText fragment = (FragmentEditText) getFragmentManager().findFragmentByTag(FragmentEditText.TAG);
if(fragment != null){
fragment.getStringObservable().subscribe(s -> textView.setText(s));
}
}複製代碼
來看看效果:
固然,這裏還有個問題
總結:
前幾天我在Reddit上看到一我的的回覆:
I think EventBus on android is popular because people don't know how to share a java object reference between android components like a Fragment and an Activity, or 2 Activities and so on. So basically I think people don't know how 2 Activites can observe the same object for data changes which I think comes from the fact that we still don't know how to architect our apps properly.
我認爲 EventBus在Android上火爆的緣由是人們不知道怎麼去在Android組件,例如Activity/Fragment之間共享一個Java對象的引用。
這個回覆能夠說應該是觸到了不少人的痛點。不少狀況咱們用EventBus僅僅是不知道如何在多個Fragment/Activity之間共享一個對象。EventBus的作法是在Bus裏登記全部的接受者。這點在RxJava裏相似,Subject/ConnectableObservable 都有相似的功能。但問題是EventBus做爲一個全局Bus,各類不一樣類型的事件管理會很麻煩(雖然EventBus把這些事給你作好了,RxBus要本身弄)。咱們有了RxJava徹底能夠避免不一樣事件的管理。相同事件封裝成對應Observable,根據需求選擇訂閱。這樣保持了類型安全,提升了性能,邏輯更清晰。
想想,本身使用EventBus是否是也是這個緣由呢?