<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ### RxJava 的適用場景和使用方式 #### 1. 與 Retrofit 的結合 > Retrofit 是 Square 的一個著名的網絡請求庫。沒有用過 Retrofit 的可以選擇跳過這一小節也沒關系,我舉的每種場景都只是個例子,而且例子之間并無前后關聯,只是個拋磚引玉的作用,所以你跳過這里看別的場景也可以的。 Retrofit 除了提供了傳統的 Callback 形式的 API,還有 RxJava 版本的 Observable 形式 API。下面我用對比的方式來介紹 Retrofit 的 RxJava 版 API 和傳統版本的區別。 以獲取一個 User 對象的接口作為例子。使用Retrofit 的傳統 API,你可以用這樣的方式來定義請求: ~~~ @GET("/user") public void getUser(@Query("userId") String userId, Callback<User> callback); ~~~ 在程序的構建過程中, Retrofit 會把自動把方法實現并生成代碼,然后開發者就可以利用下面的方法來獲取特定用戶并處理響應: ~~~ getUser(userId, new Callback<User>() { @Override public void success(User user) { userView.setUser(user); } @Override public void failure(RetrofitError error) { // Error handling ... } }; ~~~ 而使用 RxJava 形式的 API,定義同樣的請求是這樣的: ~~~ @GET("/user") public Observable<User> getUser(@Query("userId") String userId); ~~~ 使用的時候是這樣的: ~~~ getUser(userId) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<User>() { @Override public void onNext(User user) { userView.setUser(user); } @Override public void onCompleted() { } @Override public void onError(Throwable error) { // Error handling ... } }); ~~~ 看到區別了嗎? 當 RxJava 形式的時候,Retrofit 把請求封裝進 Observable ,在請求結束后調用 onNext() 或在請求失敗后調用 onError()。 對比來看, Callback 形式和 Observable 形式長得不太一樣,但本質都差不多,而且在細節上 Observable 形式似乎還比 Callback 形式要差點。那 Retrofit 為什么還要提供 RxJava 的支持呢? 因為它好用啊!從這個例子看不出來是因為這只是最簡單的情況。而一旦情景復雜起來, Callback 形式馬上就會開始讓人頭疼。比如: 假設這么一種情況:你的程序取到的 User 并不應該直接顯示,而是需要先與數據庫中的數據進行比對和修正后再顯示。使用 Callback 方式大概可以這么寫: ~~~ getUser(userId, new Callback<User>() { @Override public void success(User user) { processUser(user); // 嘗試修正 User 數據 userView.setUser(user); } @Override public void failure(RetrofitError error) { // Error handling ... } }; ~~~ 有問題嗎? 很簡便,但不要這樣做。為什么?因為這樣做會影響性能。數據庫的操作很重,一次讀寫操作花費 10~20ms 是很常見的,這樣的耗時很容易造成界面的卡頓。所以通常情況下,如果可以的話一定要避免在主線程中處理數據庫。所以為了提升性能,這段代碼可以優化一下: ~~~ getUser(userId, new Callback<User>() { @Override public void success(User user) { new Thread() { @Override public void run() { processUser(user); // 嘗試修正 User 數據 runOnUiThread(new Runnable() { // 切回 UI 線程 @Override public void run() { userView.setUser(user); } }); }).start(); } @Override public void failure(RetrofitError error) { // Error handling ... } }; 性能問題解決,但……這代碼實在是太亂了,迷之縮進啊!雜亂的代碼往往不僅僅是美觀問題,因為代碼越亂往往就越難讀懂,而如果項目中充斥著雜亂的代碼,無疑會降低代碼的可讀性,造成團隊開發效率的降低和出錯率的升高。 這時候,如果用 RxJava 的形式,就好辦多了。 RxJava 形式的代碼是這樣的: getUser(userId) .doOnNext(new Action1<User>() { @Override public void call(User user) { processUser(user); }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<User>() { @Override public void onNext(User user) { userView.setUser(user); } @Override public void onCompleted() { } @Override public void onError(Throwable error) { // Error handling ... } }); ~~~ 后臺代碼和前臺代碼全都寫在一條鏈中,明顯清晰了很多。 再舉一個例子:假設 /user 接口并不能直接訪問,而需要填入一個在線獲取的 token ,代碼應該怎么寫? Callback 方式,可以使用嵌套的 Callback: ~~~ @GET("/token") public void getToken(Callback<String> callback); @GET("/user") public void getUser(@Query("token") String token, @Query("userId") String userId, Callback<User> callback); ... getToken(new Callback<String>() { @Override public void success(String token) { getUser(token, userId, new Callback<User>() { @Override public void success(User user) { userView.setUser(user); } @Override public void failure(RetrofitError error) { // Error handling ... } }; } @Override public void failure(RetrofitError error) { // Error handling ... } }); ~~~ 倒是沒有什么性能問題,可是迷之縮進毀一生,你懂我也懂,做過大項目的人應該更懂。 而使用 RxJava 的話,代碼是這樣的: ~~~ @GET("/token") public Observable<String> getToken(); @GET("/user") public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId); ... getToken() .flatMap(new Func1<String, Observable<User>>() { @Override public Observable<User> onNext(String token) { return getUser(token, userId); }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<User>() { @Override public void onNext(User user) { userView.setUser(user); } @Override public void onCompleted() { } @Override public void onError(Throwable error) { // Error handling ... } }); ~~~ 用一個 flatMap() 就搞定了邏輯,依然是一條鏈。看著就很爽,是吧? 2016/03/31 更新,加上我寫的一個 Sample 項目: [rengwuxian RxJava Samples](https://github.com/rengwuxian/RxJavaSamples) 好,Retrofit 部分就到這里。 ### 2. RxBinding [RxBinding](https://github.com/JakeWharton/RxBinding) 是 Jake Wharton 的一個開源庫,它提供了一套在 Android 平臺上的基于 RxJava 的 Binding API。所謂 Binding,就是類似設置 OnClickListener 、設置 TextWatcher 這樣的注冊綁定對象的 API。 舉個設置點擊監聽的例子。使用 RxBinding ,可以把事件監聽用這樣的方法來設置: ~~~ Button button = ...; RxView.clickEvents(button) // 以 Observable 形式來反饋點擊事件 .subscribe(new Action1<ViewClickEvent>() { @Override public void call(ViewClickEvent event) { // Click handling } }); ~~~ 看起來除了形式變了沒什么區別,實質上也是這樣。甚至如果你看一下它的源碼,你會發現它連實現都沒什么驚喜:它的內部是直接用一個包裹著的 setOnClickListener() 來實現的。然而,僅僅這一個形式的改變,卻恰好就是 RxBinding 的目的:擴展性。通過 RxBinding 把點擊監聽轉換成 Observable 之后,就有了對它進行擴展的可能。擴展的方式有很多,根據需求而定。一個例子是前面提到過的 throttleFirst() ,用于去抖動,也就是消除手抖導致的快速連環點擊: ~~~ RxView.clickEvents(button) .throttleFirst(500, TimeUnit.MILLISECONDS) .subscribe(clickAction); ~~~ 如果想對 RxBinding 有更多了解,可以去它的 GitHub 項目 下面看看。 ### 3. 各種異步操作 前面舉的 Retrofit 和 RxBinding 的例子,是兩個可以提供現成的 Observable 的庫。而如果你有某些異步操作無法用這些庫來自動生成 Observable,也完全可以自己寫。例如數據庫的讀寫、大圖片的載入、文件壓縮/解壓等各種需要放在后臺工作的耗時操作,都可以用 RxJava 來實現,有了之前幾章的例子,這里應該不用再舉例了。 ### 4. RxBus RxBus 名字看起來像一個庫,但它并不是一個庫,而是一種模式,它的思想是使用 RxJava 來實現了 EventBus ,而讓你不再需要使用 Otto 或者 GreenRobot 的 EventBus。至于什么是 RxBus,可以看[這篇文章](http://nerds.weddingpartyapp.com/tech/2014/12/24/implementing-an-event-bus-with-rxjava-rxbus/)。順便說一句,Flipboard 已經用 RxBus 替換掉了 Otto ,目前為止沒有不良反應。 #### 最后 對于 Android 開發者來說, RxJava 是一個很難上手的庫,因為它對于 Android 開發者來說有太多陌生的概念了。可是它真的很牛逼。因此,我寫了這篇《給 Android 開發者的 RxJava 詳解》,希望能給始終搞不明白什么是 RxJava 的人一些入門的指引,或者能讓正在使用 RxJava 但仍然心存疑惑的人看到一些更深入的解析。無論如何,只要能給各位同為 Android 工程師的你們提供一些幫助,這篇文章的目的就達到了。 再次感謝對這篇文章的產出提供支持的各位: 技術支持:[流火楓林](http://weibo.com/wowwing) 內測讀者:[代碼家](http://weibo.com/daimajia)、[鮑永章](http://weibo.com/u/3224930551)、[drakeet](https://github.com/drakeet)、[馬琳](https://github.com/androidmalin)、[有時放縱](http://weibo.com/kevingracie)、[程序亦非猿](http://weibo.com/alancheeen)、[大頭鬼](http://weibo.com/brucefromsdu)、[XZoomEye](http://weibo.com/u/2662418685)、[席德雨](http://weibo.com/shadev)、[TCahead](http://weibo.com/tcahead)、[Tiiime](http://weibo.com/u/1963663403)、[Ailurus](http://weibo.com/208087666)、[宅學長](http://weibo.com/seniorszhai)、[妖孽](http://naotou.github.io/)、[大大大大大臣哥](http://weibo.com/u/3214362483?is_hot=1&noscale_head=1#_0)、NicodeLee 贊助方:周伯通招聘 是他們讓我的文章能夠以不那么丑陋的樣子出現在大家面前。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看