前言
Rxjava
由于其基于事件流的鏈式調用、邏輯簡潔 & 使用簡單的特點,深受各大 Android
開發者的歡迎。
如果還不了解RxJava,請看文章:Android:這是一篇 清晰 & 易懂的Rxjava 入門教程
- 今天,我將為大家帶來
Rxjava
的的基本使用 & 實際應用案例教學,即常見開發應用場景實現 ,并結合常用相關框架如Retrofit
等,希望大家會喜歡。
Carson帶你學RxJava系列文章,包括 原理、操作符、應用場景、背壓等等,請關注看文章:Android:這是一份全面 & 詳細的RxJava學習指南
目錄
1. 簡介
RxJava
的簡介如下
2. 基本使用
-
Rxjava
的使用方式有兩種:
方式1:分步驟實現
示意圖
方式2:基于事件流的鏈式調用 具體使用
請看文章Android RxJava:面向初學者的RxJava使用指南
3. 實際開發應用場景
-
RxJava
的實際開發應用場景 與 其對應的操作符息息相關 - 常見的
RxJava
實際開發應用場景有如下:
- 下面,我將對每個實際開發應用場景進行實例講解教學
下面實例皆結合常用框架如
Retrofit
、RxBinding
、RxBus
等
3.1 網絡請求輪詢(無條件)
-
需求場景
示意圖
3.2 網路請求輪詢(有條件)
-
需求場景
示意圖 - 具體實現
Android RxJava 實際應用講解:(有條件)網絡請求輪詢
3.3 網絡請求出錯重連
-
需求場景
示意圖 功能需求說明
- 功能邏輯
3.4 網絡請求嵌套回調
- 背景
需要進行嵌套網絡請求:即在第1個網絡請求成功后,繼續再進行一次網絡請求
如 先進行 用戶注冊 的網絡請求, 待注冊成功后回再繼續發送 用戶登錄 的網絡請求
- 沖突
嵌套實現網絡請求較為復雜,即嵌套調用函數
下面展示的是結合
Retrofit
與RxJava
的基本用法,即未用操作符前
// 發送注冊網絡請求的函數方法
private void register() {
api.register(new RegisterRequest())
.subscribeOn(Schedulers.io()) //在IO線程進行網絡請求
.observeOn(AndroidSchedulers.mainThread()) //回到主線程去處理請求結果
.subscribe(new Consumer<RegisterResponse>() {
@Override
public void accept(RegisterResponse registerResponse) throws Exception {
Toast.makeText(MainActivity.this, "注冊成功", Toast.LENGTH_SHORT).show();
login(); //注冊成功, 調用登錄的方法
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(MainActivity.this, "注冊失敗", Toast.LENGTH_SHORT).show();
}
});
}
// 發送登錄網絡請求的函數方法
private void login() {
api.login(new LoginRequest())
.subscribeOn(Schedulers.io()) //在IO線程進行網絡請求
.observeOn(AndroidSchedulers.mainThread()) //回到主線程去處理請求結果
.subscribe(new Consumer<LoginResponse>() {
@Override
public void accept(LoginResponse loginResponse) throws Exception {
Toast.makeText(MainActivity.this, "登錄成功", Toast.LENGTH_SHORT).show();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(MainActivity.this, "登錄失敗", Toast.LENGTH_SHORT).show();
}
});
}
解決方案
結合RxJava2
中的變換操作符FlatMap()
實現嵌套網絡請求
3.5 從磁盤 / 內存緩存中 獲取緩存數據
-
需求場景
示意圖 -
功能說明
對于從磁盤 / 內存緩存中 獲取緩存數據 的功能邏輯如下:
示意圖
3.6 合并數據源
- 需求場景
功能說明
即,同時向2個數據源獲取數據 -> 合并數據 -> 統一展示到客戶端
3.7 聯合判斷
- 需求場景
需要同時對多個事件進行聯合判斷
如,填寫表單時,需要表單里所有信息(姓名、年齡、職業等)都被填寫后,才允許點擊 "提交" 按鈕
功能說明
此處采用 填寫表單 作為聯合判斷功能展示,即,表單里所有信息(姓名、年齡、職業等)都被填寫后,才允許點擊 "提交" 按鈕
3.8 線程控制(切換 / 調度 )
- 需求場景
即,新開工作線程執行耗時操作;待執行完畢后,切換到主線程實時更新UI
- 具體實現
Android RxJava:細說 線程控制(切換 / 調度 )(含Retrofit實例講解)
3.9 功能防抖
-
需求場景
示意圖 功能說明
3.10 聯想搜索優化
-
需求場景
示意圖
-
功能說明
示意圖
3.11 控制被觀察者發送事件 & 觀察者接收事件速度:背壓
a. 背景
- 觀察者 & 被觀察者 之間存在2種訂閱關系:同步 & 異步。具體如下:
- 對于異步訂閱關系,存在 被觀察者發送事件速度 與觀察者接收事件速度 不匹配的情況
- 發送 & 接收事件速度 = 單位時間內 發送&接收事件的數量
- 大多數情況,主要是 被觀察者發送事件速度 > 觀察者接收事件速度
b. 沖突
- 被觀察者 發送事件速度太快,而觀察者 來不及接收所有事件,從而導致觀察者無法及時響應 / 處理所有發送過來事件的問題,最終導致緩存區溢出、事件丟失 & OOM
- 如,點擊按鈕事件:連續過快的點擊按鈕10次,則只會造成點擊2次的效果;
- 解釋:因為點擊速度太快了,所以按鈕來不及響應
下面再舉個例子:
- 被觀察者的發送事件速度 = 10ms / 個
- 觀察者的接收事件速度 = 5s / 個
即出現發送 & 接收事件嚴重不匹配的問題
Observable.create(new ObservableOnSubscribe<Integer>() {
// 1. 創建被觀察者 & 生產事件
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
for (int i = 0; ; i++) {
Log.d(TAG, "發送了事件"+ i );
Thread.sleep(10);
// 發送事件速度:10ms / 個
emitter.onNext(i);
}
}
}).subscribeOn(Schedulers.io()) // 設置被觀察者在io線程中進行
.observeOn(AndroidSchedulers.mainThread()) // 設置觀察者在主線程中進行
.subscribe(new Observer<Integer>() {
// 2. 通過通過訂閱(subscribe)連接觀察者和被觀察者
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "開始采用subscribe連接");
}
@Override
public void onNext(Integer value) {
try {
// 接收事件速度:5s / 個
Thread.sleep(5000);
Log.d(TAG, "接收到了事件"+ value );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "對Error事件作出響應");
}
@Override
public void onComplete() {
Log.d(TAG, "對Complete事件作出響應");
}
});
- 結果
由于被觀察者發送事件速度 > 觀察者接收事件速度,所以出現流速不匹配問題,從而導致OOM
示意圖
c. 解決方案
采用 背壓策略
至此,關于RxJava
常見的實際開發應用場景講解完畢。
4. 總結
- 本文主要對
RxJava2
中常用的實際開發應用場景講解進行了詳細介紹,下面用1張圖進行總結
- Carson帶你學RxJava系列文章:
入門
Carson帶你學Android:這是一篇清晰易懂的Rxjava入門教程
Carson帶你學Android:面向初學者的RxJava使用指南
Carson帶你學Android:RxJava2.0到底更新了什么?
原理
Carson帶你學Android:圖文解析RxJava原理
Carson帶你學Android:手把手帶你源碼分析RxJava
使用教程:操作符
Carson帶你學Android:RxJava操作符教程
Carson帶你學Android:RxJava創建操作符
Carson帶你學Android:RxJava功能性操作符
Carson帶你學Android:RxJava過濾操作符
Carson帶你學Android:RxJava組合/合并操作符
Carson帶你學Android:RxJava變換操作符
Carson帶你學Android:RxJava條件/布爾操作符
實戰
Carson帶你學Android:什么時候應該使用Rxjava?(開發場景匯總)
Carson帶你學Android:RxJava線程控制(含實例講解)
Carson帶你學Android:圖文詳解RxJava背壓策略
Carson帶你學Android:RxJava、Retrofit聯合使用匯總(含實例教程)
Carson帶你學Android:優雅實現網絡請求嵌套回調
Carson帶你學Android:網絡請求輪詢(有條件)
Carson帶你學Android:網絡請求輪詢(無條件)
Carson帶你學Android:網絡請求出錯重連(結合Retrofit)
Carson帶你學Android:合并數據源
Carson帶你學Android:聯想搜索優化
Carson帶你學Android:功能防抖
Carson帶你學Android:從磁盤/內存緩存中獲取緩存數據
Carson帶你學Android:聯合判斷
歡迎關注Carson_Ho的簡書
不定期分享關于安卓開發的干貨,追求短、平、快,但卻不缺深度。