|
| 1 | +用RxJava替代EventBus |
| 2 | +--- |
| 3 | + |
| 4 | +> * 原文链接 : [use Rxjava instead of Event Bus libraries](https://medium.com/mobiwise-blog/use-rxjava-instead-of-event-bus-libraries-aa78b5023097#.k0ecseaz7) |
| 5 | +* 原文作者 : [Muratcanbur](https://medium.com/@muratcanbur) |
| 6 | +* 译文出自 : [开发技术前线 www.devtf.cn](http://www.devtf.cn) |
| 7 | +* 转载声明: 本译文已授权[开发者头条](http://toutiao.io/download)享有独家转载权,未经允许,不得转载! |
| 8 | +* 译者 : [XWZack](https://github.com/XWZack) |
| 9 | +* 校对者: [Mr.Simple](https://github.com/bboyfeiyu) |
| 10 | +* 状态 : 校对中 ` |
| 11 | + |
| 12 | +In Android community, everyone is talking about RxJava and why we should use RxJava in Android projects. After start implementing RxJava in our Android application, we noticed that we don’t need Otto(or any other event bus libraries) implemented in our code base. In this blog post, I am going to show how we got rid of Otto in our code base, start using RxJava instead. |
| 13 | + |
| 14 | +在Android社区,每个人都在讨论RxJava,以及为什么我们应该在Android项目中使用RxJava。当我们开始在Android项目中实现RxJava后,我们注意到,我们的项目不需要引入Otto(或任何其他事件总线库)。通过这篇博客,我将展示我们是如何在项目中用RxJava替代Otto的。 |
| 15 | + |
| 16 | + |
| 17 | +# let me tell you how we implemented MVP pattern into our code base |
| 18 | +# 我们项目中的MVP模式是怎么实现的 |
| 19 | + |
| 20 | +When we started developing Radyoland app which is a radio streaming application, We decided to use MVP pattern to design our code base, project structure and etc. We have splitted into some layers (domain, model, app and etc.) |
| 21 | + |
| 22 | +开始开发我们的无线流媒体应用Radyoland的时候,我们决定使用MVP模式来设计我们的代码底层,项目架构等。我们已经分成了几层(domain,model,app等) |
| 23 | + |
| 24 | + |
| 25 | + |
| 26 | +In the model layer, we have classes and interfaces for RESTful operations. In domain layer, we tried to implement our business logic for application so that we created some usecase classes. |
| 27 | + |
| 28 | +在model层,我们有基于RESTful的类和接口。在domain层,我们试图实现应用程序的业务逻辑,所以我们写了一些用例类。 |
| 29 | + |
| 30 | +# Why did we use event bus library in the first place? |
| 31 | +# 为什么我们当初使用event bus? |
| 32 | + |
| 33 | +if you have more than one layer in your Android application, that means you need to transfer data between these layers. In our case, we think if we define a BusUtil class for both DataBus and UI Bus, we can easily transfer data between these layers(model, domain, presentation). |
| 34 | + |
| 35 | +如果你的Android应用超过一层,这就意味着你需要在这些层之间传输数据。就我们而言,我们认为,如果我们为数据总线和UI总线定义一个BusUtil类,我们就可以轻松地在这些层(model,domain,presentation)之间传输数据。 |
| 36 | + |
| 37 | +You can “subscribe” to and “unsubscribe” from specific events posted by the bus. Logic behind this method works like this way. |
| 38 | + |
| 39 | +你可以“订阅” ,并从总线发布的特定事件“取消订阅” 。这种方法背后的逻辑是这样运作的。 |
| 40 | + |
| 41 | +in our UsecaseController, PresenterImp classes, we post an event requesting data described in our REST implementation classes and subscribed to this event. |
| 42 | + |
| 43 | +在我们的UsecaseController,PresenterImp类中,我们发出一个事件,请求REST实现类中描述的数据并且订阅此事件。 |
| 44 | + |
| 45 | +``` |
| 46 | +@Override |
| 47 | +public void getRadioList() { |
| 48 | + Call<RadioWrapper> radioWrapperCall = restInterface.getRadioList(); |
| 49 | + radioWrapperCall.enqueue(new Callback<RadioWrapper>() { |
| 50 | + @Override |
| 51 | + public void onResponse(Response<RadioWrapper> response, Retrofit retrofit) { |
| 52 | + dataBus.post(response.body()); |
| 53 | + } |
| 54 | +
|
| 55 | + @Override |
| 56 | + public void onFailure(Throwable t) { |
| 57 | + Timber.e(t.getMessage()); |
| 58 | + } |
| 59 | + }); |
| 60 | +} |
| 61 | +``` |
| 62 | +When we call an asynchronous data request method with a callback argument, We use the bus to post the result data and subscribes to the result event. |
| 63 | + |
| 64 | +当我们调用了带有回调参数的异步数据请求方法,我们用总线发布结果数据,并订阅该事件。 |
| 65 | + |
| 66 | +``` |
| 67 | +@Subscribe |
| 68 | +@Override |
| 69 | +public void onRadioListLoaded(RadioWrapper radioWrapper) { |
| 70 | + new SaveDatabase(radioWrapper, databaseSource).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
| 71 | + uiBus.post(radioWrapper); |
| 72 | +} |
| 73 | +``` |
| 74 | +and post it to update the UI. The activity or fragment should subscribe to events in onResume() and unsubscribes in onPause(). |
| 75 | + |
| 76 | +然后发布数据以更新UI 。activity或fragment应该在onResume()中订阅事件并在onPause()中解除订阅 。 |
| 77 | + |
| 78 | +``` |
| 79 | +@Subscribe |
| 80 | +@Override |
| 81 | +public void onRadioListLoaded(RadioWrapper radioWrapper) { |
| 82 | + radioListView.onListLoaded(radioWrapper); |
| 83 | + radioListView.dismissLoading(); |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +This implementation technique works well. As we are good Android developers, always try find better ways to do. We found a way to get rid of all callback and subscribe methods. We decided to use RxJava and RxAndroid for our Android application codebase. |
| 88 | + |
| 89 | +这种实现方法效果还不错。但由于我们是优秀的Android程序猿,总是追求更好的解决方案。我们找到了一个方案,可以摆脱所有的回调和订阅方法。我们决定在代码中使用RxJava和RxAndroid。 |
| 90 | + |
| 91 | +# let me tell you how we implemented Rxjava |
| 92 | +我们是怎么实现Rxjava的 |
| 93 | + |
| 94 | +First of all, We needed to change all method return types in RestInterface. |
| 95 | + |
| 96 | +首先,我们需要改变所有RestInterface的返回类型 。 |
| 97 | + |
| 98 | +without RxJava; |
| 99 | + |
| 100 | +在没有RxJava的情况下 ; |
| 101 | + |
| 102 | +``` |
| 103 | +@GET("") |
| 104 | +Call<RadioWrapper> getRadioList(); |
| 105 | +``` |
| 106 | + |
| 107 | +with RxJava, |
| 108 | + |
| 109 | +有了Rxjava |
| 110 | + |
| 111 | +``` |
| 112 | +@GET("") |
| 113 | +Observable<RadioWrapper> getRadioList(); |
| 114 | +``` |
| 115 | + |
| 116 | +in REST implementation class, we had API call methods. I shared one of them. After started using RxJava, we need to change this method implementations. We changed method return types to Observable. After doing neccessary changes, method looks like that. |
| 117 | + |
| 118 | +在REST实现类中,我们有API调用方法。我分享了其中的一个。使用RxJava启动后,我们需要改变这种方法的实现。我们把方法的返回类型改成Observable。经过了必要的改变后,方法看起来像这样。 |
| 119 | + |
| 120 | +``` |
| 121 | +@RxLogObservable |
| 122 | +@Override |
| 123 | +public Observable<RadioWrapper> getRadioList() { |
| 124 | + return restInterface.getRadioList(); |
| 125 | +} |
| 126 | +``` |
| 127 | +We are done with REST implementation class. After this, We need to change usecase implementation class and methods. |
| 128 | + |
| 129 | +我们完成了REST实现类。在此之后,我们需要改变用例的实现类和方法。 |
| 130 | + |
| 131 | +``` |
| 132 | +@Override |
| 133 | +public Observable<RadioWrapper> getRadioList() { |
| 134 | +
|
| 135 | + /** |
| 136 | + * Get radiolist observable from Cache |
| 137 | + */ |
| 138 | + Observable<RadioWrapper> radioListDB = databaseSource.getRadioList() |
| 139 | + .filter(radioWrapper -> radioWrapper.radioList.size() > 0) |
| 140 | + .subscribeOn(Schedulers.computation()); |
| 141 | +
|
| 142 | + /** |
| 143 | + * Load radiolist from api layer and save it to DB. |
| 144 | + */ |
| 145 | + Observable<RadioWrapper> radioListApi = apiSource.getRadioList() |
| 146 | + .doOnNext(radioWrapper -> { |
| 147 | + Observable.create(subscriber -> { |
| 148 | + databaseSource.save(radioWrapper); |
| 149 | + subscriber.onCompleted(); |
| 150 | + }).subscribeOn(Schedulers.computation()).subscribe(); |
| 151 | + }) |
| 152 | + .subscribeOn(Schedulers.io()); |
| 153 | +
|
| 154 | + /** |
| 155 | + * concat db and api observables |
| 156 | + */ |
| 157 | + return Observable |
| 158 | + .concat(radioListDB, radioListApi) |
| 159 | + .observeOn(AndroidSchedulers.mainThread()); |
| 160 | +
|
| 161 | +} |
| 162 | +``` |
| 163 | +right now, our method getRadioList return an Observable stream data to our UI. As you can see, we don’ t need to send our data through an event bus. You can also filter, combine, cache, or manipulate this stream data depending on your need. |
| 164 | + |
| 165 | +现在,我们的方法getRadioList返回一个Observable stream到我们的UI。正如你所看到的,我们根本不 |
| 166 | +需要通过事件总线发送数据。你还可以过滤,合并,缓存,或根据你的需要操作这个数据流。 |
| 167 | + |
| 168 | +# What we have learned |
| 169 | +# 我们学到了什么 |
| 170 | + |
| 171 | +Although using RxJava is not so easy to use, replacing Otto with RxJava has removed many boilerplate callback code block from our codebase. In my opinion, RxJava is the best option for getting asynchronous data requests from any REST API. |
| 172 | +if you have better ways to do it, feel free to comment here, or share an example repo. |
| 173 | + |
| 174 | +虽然RxJava也不是那么好用,但是通过使用RxJava替换Otto,我们已经从代码中删除了许多冗余的回调代码块。在我看来,对于任何REST API的异步数据请求,RxJava都是最佳选择。 |
| 175 | +如果你有更好的解决方法,请随意在这里评论或分享例子。 |
| 176 | + |
0 commit comments