1. 程式人生 > >RxJava與Retrofit實戰總結

RxJava與Retrofit實戰總結

一、ReactiveX簡單介紹

Rx是一個使用可觀察資料流進行非同步程式設計的程式設計介面,ReactiveX結合了觀察者模式、迭代器模式和函數語言程式設計的精華。Rx提供了一系列的操作符,你可以使用它們來過濾(filter)、選擇(select)、變換(transform)、結合(combine)和組合(compose)多個Observable,這些操作符讓執行和複合變得非常高效。

在ReactiveX中,一個觀察者(Observer)訂閱一個可觀察物件(Observable)。觀察者對Observable發射的資料或資料序列作出響應。這種模式可以極大地簡化併發操作,因為它建立了一個處於待命狀態的觀察者哨兵,在未來某個時刻響應Observable的通知,不需要阻塞等待Observable發射資料。

上圖取自ReactiveX官方文件,上面一排圖示代表被觀察物件產生的事件,橫向的箭頭代表時間線,有6個事件依次發射,經過中間的轉換和處理得到了下面的圖示,即處理結果,有些事件發射、處理和接收都成功,而有些事件因為各種原因導致失敗,這些情況都會在相應的回撥方法中呈現。

Subscribe方法用於將觀察者連線到Observable,你的觀察者需要實現以下方法的一個子集:

  • onNext(T item)

    Observable呼叫這個方法發射資料,方法的引數就是Observable發射的資料,這個方法可能會被呼叫多次,取決於你的實現。

  • onError(Exception ex)

    當Observable遇到錯誤或者無法返回期望的資料時會呼叫這個方法,這個呼叫會終止Observable,後續不會再呼叫onNext和onCompleted,onError方法的引數是丟擲的異常。

  • onComplete

    正常終止,如果沒有遇到錯誤,Observable在最後一次呼叫onNext之後呼叫此方法。

根據Observable協議的定義,onNext可能會被呼叫零次或者很多次,最後會有一次onCompleted或onError呼叫(不會同時),傳遞資料給onNext通常被稱作發射,onCompleted和onError被稱作通知。

二、RxJava與RxAndroid的配合使用

RxJava是 ReactiveX 在JVM上的一個實現,ReactiveX使用Observable序列組合非同步和基於事件的程式。RxJava提供了5種排程器,分別是:

  • .io()

    這個排程器時用於I/O操作。它基於根據需要,增長或縮減來自適應的執行緒池。由於它專用於I/O操作,所以並不是RxJava的預設方法;正確的使用它是由開發者決定的。重點需要注意的是執行緒池是無限制的,大量的I/O排程操作將建立許多個執行緒並佔用記憶體。

  • .computation()

    這個是計算工作預設的排程器,它與I/O操作無關。它也是許多RxJava方法的預設排程器:buffer(), debounce(), delay() , interval(), sample(), skip()。

  • .immediate()

    這個排程器允許你立即在當前執行緒執行你指定的工作。它是timeout(),timeInterval(),以及timestamp()方法預設的排程器。

  • .newThread()

    這個排程器為指定任務啟動一個新的執行緒。

  • .trampoline()

    當我們想在當前執行緒執行一個任務時,並不是立即,我們可以用.trampoline()將它入隊。這個排程器將會處理它的佇列並且按序執行佇列中每一個任務。它是repeat()和retry()方法預設的排程器。

RxAndroid模組包含RxJava的Android特定的繫結程式碼。它給RxJava添加了一些類,用於幫助在Android應用中編寫響應式(reactive)的元件。它提供了一個可以在給定的Android Handler上排程Observable的排程器 Scheduler,特別是在UI主執行緒上 AndroidSchedulers.mainThread()。

上面提到了幾種執行緒排程器,可以讓開發者在不同的執行緒執行不同的事件,那麼如何指定和切換執行緒呢?RxJava提供了兩個方法subscribeOn和observeOn,前者可以指定Observable事件產生和變換處理的執行緒,後者可以指定訂閱者所在的執行緒,假如事件是一個耗時任務,完全可以通過subscribeOn指定為計算執行緒或者子執行緒,然後再通過observeOn切換Android主執行緒,即可在訂閱者回調方法中操作UI檢視。

看一個具體的例子吧。

Observable.just("")
  .subscribeOn(Schedulers.newThread())
  .map(s -> {
    for (PerformanceEntity.Components components : performanceEntity.components) {
        PerformanceSubmitEntity.Data submitData = new PerformanceSubmitEntity.Data();
        submitData.componentId = components.id;
        for (PerformanceEntity.Data data : performanceEntity.data) {
            if (data.componentId == components.id) {
                transferData(submitData, data);
                break;
            }
        }
        submitDataList.add(submitData);
    }
    return null;
  })
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(o -> {
    initPerformanceView();
  });

在渲染檢視之前需要處理大量的資料,那麼就可以將Observable的執行緒切換至子執行緒,等負責的業務邏輯完成後再切換至UI執行緒,然後在subscribe中完成檢視的渲染。這樣即可以保證UI執行緒不會大量複雜的計算,也可以不用Handler、AsycTask等複雜的操作,程式碼清晰度也相對較高。

三、RxJava與Retrofit的結合

在Android開發中,網路請求往往是最耗時的,也是情況最複雜的,如果直接在UI執行緒進行網路請求,編譯時就會報錯,及時編譯報錯,執行時系統也會報ANR錯誤,所以網路請求必須在子執行緒完成。而網路請求結果一般又需要操作UI檢視,所以返回結果的回撥有必須在主執行緒,那麼上面提到的方法就可以完美解決這個問題。

網路請求的返回結果一般都是json格式,如果返回值為原始的字串,那麼就需要呼叫放每次都要進行json至JavaBean的轉換,有的時候我們只關心返回結果中的一部分資料,那麼就還需要在返回結果中再次對資料進行篩選,還有情況是我們只關心滿足一定條件的資料,那麼這些需求如果用RxJava來實現就變得異常簡單。有關Retrofit詳細用法,以及如何將返回結果切換成RxJava處理模式,可以閱讀Retrofit用法詳解這篇文章,下面直接看示例:

 showProgressBar();
 messageService.messageList(msgType, PAGE_INDEX, PAGE_SIZE)
            .compose(new DefaultTransformer<>(getActivity()))
            .map(messageListResponse -> messageListResponse.data)
            .flatMap(messageListEntity -> Observable.from(messageListEntity))
            .filter(messageEntity.id > 10)
            .subscribe(new Subscriber<MessageEntity>() {
                @Override
                public void onCompleted() {
                    dismissProgressBar();
                    refreshLayout.setRefreshing(false);
                }
                @Override
                public void onError(Throwable e) {
                    dismissProgressBar();
                    refreshLayout.setRefreshing(false);
                }
                @Override
                public void onNext(MessageEntity messageEntity) {
                    updateView(messageEntity);
                }
            });
  • DefaultTransformer主要實現執行緒的切換以及錯誤訊息的統一處理,一般來說服務端介面返回的資料格式都比較固定,會有code、message、data,其中code只是正確或者錯誤型別,message返回正確或者錯誤日誌,data則是業務資料的存放地,那麼就可以在DefaultTransformer中統一判斷code值,如果是請求出錯,那麼直接將異常拋給onError回撥方法。
  • map中實現的功能就是上文提到的呼叫方只關心data中的資料,而不關心code和message,那麼就可以通過map方法直接將data中的資料傳遞給訂閱者。
  • 如果我們想將返回值List逐條處理,一般的做法就是直接for迴圈,這裡用到了flatMap,就是將messageListEntity通過Observable的from方法重新拆分成更細粒度的MessageEntity,而訂閱者得到也就是MessageEntity。
  • filter方法就是通過布林表示式篩選出符合條件的資料,上述例子中就是將id值大於10的MessageEntity篩選出來。

有關Observable的compose、map、from、flatMap、filter等方法可以參考ReactiveX官方教程,中文環境下可以參考給Android開發者的RxJava詳解

歡迎大家關注我的微信公眾號藍田大營,下面是微信公眾號二維碼:

微信公眾號藍田大營二維碼

相關推薦

RxJavaRetrofit實戰總結

一、ReactiveX簡單介紹 Rx是一個使用可觀察資料流進行非同步程式設計的程式設計介面,ReactiveX結合了觀察者模式、迭代器模式和函數語言程式設計的精華。Rx提供了一系列的操作符,你可以使用它們來過濾(filter)、選擇(select)、變換(tr

OKhttp、RXjavaretrofit的網路訪問使用

兩個月沒有寫微博了,無論如何,現在再次迴歸Android的打怪升級。 關於Rxjava的學習和介紹,有興趣的可以去雲盤中提取pdf資料,這裡不做詳解,地址和提取碼如下:連結:http://pan.baidu.com/s/1skDOjN3 密碼: ajv7。 要想

RxJavaRetrofit學習記錄(一)

原文地址https://gank.io/post/56e80c2c677659311bed9841專案結構1、原生Retrofit請求 /** * 原生Retrofit請求 */ private void todo1() { Re

安卓rxJavaretrofit配置示例

結合當前比較火的mvp開發模式,在AndroidStudio上使用rxJava與retrofit。rxJava(非同步),retrofit(網路請求)1.gradle新增依賴 compile 'com.google.code.gson:gson:2.4' com

RxJava整合Retrofit遇到的問題總結

exception 實現 請求 serve 執行過程 color 相對 row ima 一:初上手(填坑)   Observable將事件序列執行完畢後,會回調Observe的onNext()方法和onCompleted()方法,當出現異常/錯誤時會調用onError()

REST無縫結合-RxJavaRetrofit

在上一章中,我們學習瞭如何使用排程器在不同於UI執行緒的執行緒上操作。我們學習瞭如何高效的執行I/O任務而不用阻塞UI以及如何執行耗時的計算任務而不耗損應用效能。在最後一章中,我們將建立一個最終版的真實世界的例子,用Retrofit對映到遠端的API,非同步

【Mybatis】深入淺出Mybatis基礎原理實戰 總結

         Mybatis是Java的持久層框架,將SQL寫在xml中,便於統一管理。hibernate也是一套優秀的ORM框架,但是存在一些不足,如,全表對映帶來的效能降低,多表關聯和複雜s

人臉識別技術原理工程實踐(10個月人臉識別領域實戰總結

1人臉識別應用場景(驗證) 我們先來看看人臉識別的幾個應用。第一個是蘋果的FACE ID,自從蘋果推出FaceID後,業界對人臉識別的應用好像信心大增,各種人臉識別的應用從此開始“野蠻生長”。 事實上,人臉識別技術在很多場景的應用確實可以提升認證效率,同時提升使用者體驗。前兩

mybatisoracle使用總結

date() oracle .get datetime ide 整型 有效 conn 時間 Oracle使用總結 1、新建表刪除表 新建表語句: CREATE TABLE +表名{ } create table AFA_USER ( USER_ID

MySQL Proxy 讀寫分離(實戰總結

mysql proxy;讀寫分離 規劃: 主mysql服務器:192.168.1.21 從mysql服務器: 192.168.1.22 mysql讀寫分離器:192.168.1.23 1、讀寫分離服務器上解壓安裝包,並添加對應用戶,並編輯啟動腳本; # tar xf mysql-proxy-

zabbix   監控平臺搭建過程中的報錯解決方法總結

監控 zabbix 運維自動化1.php option post_max_size 2.php option max_execution_time 3.php option max_input_time 4.php time zone 5.php bcm

Vue.js 實戰總結

體會 git api display int 最新 團隊 輕量 開始 最近在某個項目中用到了Vue.js,從上手做開發到項目發布,一步步踩了不少坑。本文試圖總結過去一個多月使用Vue.js中的一些經驗,也算是一點心得體會吧,拿出來與大家分享,歡迎多多交流。 Vue.js簡

Android 5.x Theme ToolBar 實戰

出了 @override chan getc sch owa listview too tle 1、概述 隨著Material Design的逐漸的普及,業內也有很多具有分享精神的夥伴翻譯了material design specification ,中文翻譯地址:Mate

用戶空間內核空間,進程上下文中斷上下文[總結]【轉】

存儲器 com ont article 模式 tab 用戶代碼 ssi 而在 轉自:http://blog.csdn.net/lizuobin2/article/details/51791863 本文轉載自:http://www.cnblogs.com/Anker/p/3

java類的加載初始化總結

name 重復 構造器 存儲空間 iii 成員變量 垃圾處理 創建 遞歸 1、觸發類加載的原因(主動調用與被動調用):     六種主動調用:       1)、創建類的實例(new操作、反射、cloning、反序列化)       2)、調用類的靜態方法       3)

敏捷轉型中whyhow的總結

技術分享 統計 增量 實現 this 球隊 append log 動軟 敏捷轉型參考框架: 為了成功順暢地推行敏捷開發。下面將對整個敏捷轉型參考框架作個整體說明。為企業進行敏捷轉型提供基本方法參考。整個敏捷轉型參考框架主要包括5個步驟,前兩個步驟主要

字段屬性的總結比較

對象 內部 般的 bsp 特征 而不是 靜態 nbsp 外部 字段(成員變量)   字段主要是為類的內部做數據交互使用,字段一般的private。   我們可以給字段賦值,也可以取值。   當字段需要為外部提供數據時,將字段封裝為屬性,而不是共有話字段。 屬性   屬性

過濾器監聽器知識總結

mapping rem setattr 處理 event 節點 create 增加 多個 過濾器 什麽是過濾器? 過濾器是servlet2.3規範中定義的一種小型的、可插入的Web組件。用來攔截Servlet容器的請求和響應過程。以便查看、提取或以某種方式操作正在客戶機和服

Oracle VM實現管理實戰pdf

link ctf top 安裝oracle 1.3 class 任務 規模 小結 下載地址:網盤下載 內容簡介編輯《Oracle VM實現與管理實戰》提供了在企業中構建和維護動態的虛擬化平臺的詳盡信息。闡述了關鍵的虛擬化概念、操作指令、示例以及最佳實踐。探尋如何設Orac

Webpack+Vue+ES6 前端組件化開發mobile-multi-page應用實戰總結

basename and import tran alert nal 否則 push 列表 本文版權歸博客園和作者吳雙本人共同所有 轉載和爬蟲請註明原文地址 www.cnblogs.com/tdws 一.寫在前面 項目上線有一段時間了,一個基於webpack+vue