反應式編程實戰 使用 RxJava 2.x 開發 Android 應用 (RxJava for Android Developers: with ReactiveX and FRP)

Timo Tuominen 著 韓義波 譯

  • 反應式編程實戰 使用 RxJava 2.x 開發 Android 應用 (RxJava for Android Developers: with ReactiveX and FRP)-preview-1
  • 反應式編程實戰 使用 RxJava 2.x 開發 Android 應用 (RxJava for Android Developers: with ReactiveX and FRP)-preview-2
反應式編程實戰 使用 RxJava 2.x 開發 Android 應用 (RxJava for Android Developers: with ReactiveX and FRP)-preview-1

買這商品的人也買了...

商品描述

《反應式編程實戰 使用RxJava 2.x開發Android應用》首先引導讀者以反應的方式考慮編程和數據。
本書詳細介紹了Android中RxJava的核心模式,並解釋了視圖模型。
然後探討了備受追捧的應用功能,例如聊天客戶端和巧妙的轉換。
最後,讀者將瞭解與函數式反應式編程(FRP)思維緊密結合的高層設計關註點、架構方法和框架。

主要內容 
● 反應式編程簡介 
● 簡單的線程管理 
● 提高UI反應能力 
● 異步思維方式 
● 構建一個有效的聊天客戶端

作者簡介

Timo Tuominen

作為三星重大Android項目的架構師,
Timo Tuominen在與Futurice合作時已廣泛使用了FRP和Rxjavao。

目錄大綱

目  錄
第Ⅰ部分  反應式核心編程
第1章  反應式編程簡介   3
1.1  你閱讀本書的原因   3
1.2  不要閱讀本書的情形   4
1.3  OOP、Rx、FP和FRP   5
1.3.1  OOP,面向對象編程   5
1.3.2  FP,函數式編程   5
1.3.3  FRP,函數反應式編程   5
1.3.4  Rx,反應式編程   5
1.4  Rx的特徵   5
1.5  編寫的代碼就是所實現的功能   6
1.5.1  灰色代碼   7
1.5.2  反應式編程開發   7
1.6  反應式總覽   8
1.6.1  移動開發   8
1.6.2  Web和HTML5   9
1.6.3  後端系統和Rx   9
1.7  在開始學習之前你需要知道什麽   10
1.7.1  你需要具備的條件   10
1.7.2  你不需要具備的條件   10
1.8  關於本書   10
1.8.1  在線代碼示例   10
1.8.2  茶歇   11
1.9  RxJava 2和Android   11
1.9.1  為什麽選擇Java   11
1.9.2  為什麽選擇RxJava   11
1.10  設置Android環境   12
1.10.1  Google Android Studio   12
1.10.2  Git   12
1.10.3  RxJava 2依賴項   12
1.11  Java 8 lambda   12
1.11.1  什麽是lambda函數   13
1.11.2  剖析lambda函數   13
1.11.3  lambda函數有什麽優點   14
1.12  深入研究Rx:實時搜索   14
1.13  項目設置   15
1.13.1  一種快速實現   15
1.13.2  基於時間篩選文本更改   15
1.14  作為數據的emitter的文本輸入   15
1.15  發布-訂閱模式   16
1.16  作為observable的文本輸入   17
1.17  篩選observable   18
1.17.1  .filter操作符   19
1.17.2  observable和subscriber的時間解耦   20
1.18  時間延遲   20
1.19  延遲時間的優勢   21
1.20  debounce操作符   21
1.21  將代碼放入Android系統中   23
1.22  反應式編程的原理   25
1.23  事件和彈珠圖   26
1.24  本章小結   26

第2章  連接observable   29
2.1  RxJava和事件流   29
2.2  subscriber   30
2.3  RxJava 2 observable的類型   31
2.3.1  Observable   31
2.3.2  Single   31
2.3.3  Maybe   31
2.3.4  Completable   31
2.3.5  Flowable   32
2.4  訂閱並轉換不同的observable   32
2.5  當發出正常的網絡請求時會發生什麽   32
2.6  當observable發出網絡請求時會發生什麽   33
2.7  網絡請求作為observable   34
2.8  示例:RSS提要聚合器   35
2.9  提要結構   36
2.10  獲取數據   37
2.11  combineLatest操作符   37
2.12  到目前為止的Rx代碼   38
2.13  異步數據處理鏈   40
2.14  按順序排列列表   42
2.15  .map操作符   42
2.15.1  操作符的有效期   43
2.15.2  使用.map對列表進行排序   43
2.16  不變性簡介   45
2.16.1  不具有不變性的鏈   46
2.16.2  具有不可變數據的鏈   46
2.16.3  使用不變性解決問題   47
2.16.4  Java中的builder   47
2.17  錯誤處理   48
2.17.1  網絡錯誤及其處理   49
2.17.2  當真正的錯誤出現時,該怎麽辦   50
2.18  向客戶端添加更多提要   51
2.18.1  提要observable列表   51
2.18.2  細說combineLatest   51
2.18.3  有多個彈珠的combineLatest   52
2.19  本章小結   53
2.19.1  未來展望   53
2.19.2  從事件到反應式狀態   53

第3章  建立數據處理鏈   55
3.1  observable的不同角色   55
3.1.1  observable事件   55
3.1.2  反應變量   56
3.1.3  籃子中橘子的數量   56
3.2  事件與反應狀態   57
3.2.1  observable的click事件   57
3.2.2  開關按鈕   57
3.2.3  將事件轉換為狀態   57
3.2.4  作為反應變量的observable   58
3.3  observable的內部狀態   58
3.4  箭頭圖和不同的observable類型   59
3.5  示例:信用卡驗證表單   60
3.5.1  信用卡驗證器   60
3.5.2  佈局   60
3.5.3  信用卡卡號的工作原理   61
3.5.4  按步驟驗證數字   62
3.5.5  輸入   62
3.5.6  輸出   62
3.5.7  解方程式   63
3.6  第一步:有效期   63
3.7  信用卡卡號類型和校驗和   65
3.7.1  卡類型   65
3.7.2  檢查已知的CardType   67
3.7.3  計算校驗和   67
3.7.4  信用卡卡號輸入驗證的大圖   68
3.8  CVC代碼驗證   68
3.9  融會貫通   70
3.9.1  登錄FRP鏈   71
3.9.2  完整圖   71
3.10  反應式編程的抽象層次   72
3.11  RxJava的工作原理   74
3.12  本章小結   75
3.12.1  反應圖的優點   75
3.12.2  表單改進   75

第4章  通過網絡連接用戶界面   77
4.1  訂閱解釋   77
4.2  終止訂閱   79
4.2.1  已經完成的observable信號   79
4.2.2  Disposable對象用於取消訂閱   80
4.3  RxJava 2概念和訂閱管理   81
4.3.1  新subscribe函數簽名   81
4.3.2  subscribe函數重載   81
4.3.3  作為subscriber的基本consumer接口   82
4.3.4  LambdaObserver   82
4.4  高級Rx鏈示例:Flickr搜索客戶端   82
4.5  設置Flickr客戶端項目   83
4.5.1  申請API密鑰   83
4.5.2 將API放到gradle.properties中   84
4.6  搜索鏈概述   84
4.7  步驟1:簡單的硬編碼搜索   85
4.7.1  搜索API返回的數據類型   86
4.7.2  搜索並呈現   86
4.7.3  到目前為止已實現的功能   86
4.8  click事件   87
4.8.1  使用onClickListener觸發搜索   87
4.8.2  使用訂閱   88
4.8.3  管理訂閱   88
4.8.4  流式方法   88
4.9  實現反應鏈   90
4.9.1  連通數據圖   91
4.9.2  啟動鏈中的異步操作   92
4.10  switchMap的工作原理   92
4.11  獲取縮略圖信息   94
4.12  步驟1:將列表擴展為一個observable   95
4.12.1  flatMap操作符   95
4.12.2  Observable.merge   95
4.12.3  在嵌套的observable中使用merge   96
4.12.4  flatMap   97
4.12.5  使用flatMap擴展列表   97
4.12.6  代碼中的內容   97
4.13  步驟2: 分別對每一項應用操作   98
4.14  步驟3:收集結果   98
4.15  完整的解決方案   99
4.15.1  圖中間的關鍵代碼   100
4.15.2  組合代碼   100
4.16  添加來自其他API的用戶名   101
4.17  本章小結   102

第5章  高級RxJava   105
5.1  深入瞭解observable和subject   105
5.2  示例:文件瀏覽器   106
5.3  文件瀏覽器應用的用戶流   107
5.4  獲取目錄的文件列表   108
5.4.1  返回目錄內容列表的函數   109
5.4.2  Android權限   109
5.4.3  使用Observable.create創建自定義observable   109
5.4.4  將文件listing函數封裝到FileListingObservable中   110
5.4.5  文件列表observable的生命周期   111
5.5  線程基礎   112
5.5.1  什麽是線程   112
5.5.2  尚未解決的問題   113
5.5.3  具有輸入和輸出功能的函數   113
5.6  函數式編程中的線程   114
5.6.1  反應式函數鏈   114
5.6.2  顯示有副作用的結果   115
5.7  使用getFileListingObservable更改線程   115
5.7.1  線程更改   115
5.7.2  使用observeOn更改線程   116
5.7.3  使用subscribeOn更改線程   117
5.7.4  在代碼中使用subscribeOn   118
5.8  使文件列表動態化   118
5.8.1  切換到fileObservable作為源   119
5.8.2  形成完整的鏈   119
5.8.3  Observable.just   119
5.9  列表click事件   120
5.10  subject的不同類型   121
5.10.1  PublishSubject   122
5.10.2  BehaviorSubject   122
5.11  使用subject作為FileObservable   123
5.12  添加PREVIOUS和ROOT按鈕   126
5.13  PREVIOUS和ROOT的擴展圖   126
5.13.1  對兩個新按鈕進行編碼   127
5.13.2  第一個版本準備好了   128
5.14  更清晰observable的改進版本   128
5.15  PREVIOUS按鈕   129
5.16  融會貫通   130
5.17  詳細圖   131
5.18  到目前為止的完整代碼   131
5.19  保存並釋放訂閱   133
5.20  關於subject的最後說明   135
5.21  本章小結   136

第Ⅱ部分  RxJava中的架構
第6章  反應式視圖模型   141
6.1  視圖層   141
6.1.1  視圖   142
6.1.2  視圖和文件瀏覽器   142
6.2  平臺容器   143
6.2.1  平臺容器的特徵   143
6.2.2  平臺容器的生命周期   143
6.3  視圖模型   144
6.4  視圖模型的藍圖   146
6.4.1  視圖模型的特徵   147
6.4.2  將現有代碼遷移到視圖模型中   147
6.4.3  獲取視圖模型中的外部數據   148
6.4.4  視圖模型的完整構造函數   149
6.5  連接視圖和視圖模型   150
6.5.1  設置視圖和視圖模型   150
6.5.2  顯示視圖模型的輸出   151
6.5.3  將視圖模型綁定到視圖   151
6.6  全貌   153
6.7  視圖模型生命周期   154
6.7.1  在視圖模型中保存訂閱   154
6.7.2  視圖模型的代碼   154
6.8  視圖模型和Android生命周期   157
6.8.1  視圖模型Subscribe/Unsubscribe   157
6.8.2  視圖模型到視圖綁定   157
6.8.3  改進的視圖模型生命周期   158
6.8.4  全貌   158
6.8.5  Android 上的視圖模型階段   159
6.8.6  onResume和onPause的代碼   160
6.9  代碼的視圖關聯性   161
6.10  本章小結   162

第7章  反應式架構   163
7.1  反應式架構基礎   163
7.2  模型-視圖-視圖模型   164
7.2.1  拆分類   164
7.2.2  模型的內部關系   165
7.2.3  所說的數據庫是真實的數據庫嗎   165
7.3  反應模型   166
7.3.1  作為實體存儲庫的Web服務器   166
7.3.2  Web請求流程   166
7.3.3  Web服務器的模型   167
7.3.4  模型在哪裡   168
7.3.5  實體存儲庫的模型   168
7.4  從模型中檢索數據   169
7.5  修改文件瀏覽器   171
7.6  構建文件瀏覽器的模型   172
7.6.1  現有的文件瀏覽器視圖模型   172
7.6.2  將狀態從視圖模型移入模型   173
7.6.3  FileBrowser模型實現   174
7.7  使用模型   175
7.7.1  創建模型   175
7.7.2  更新視圖模型中的模型   176
7.7.3  從視圖模型中刪除邏輯   176
7.8  模型及其使用者的規則   177
7.8.1  模型是事實的唯一來源   177
7.8.2  模型首先提供最新值   177
7.8.3  模型的所有使用者都必須準備好接收更新   177
7.9  事實的唯一來源   178
7.9.1  模型是應用的維基百科   178
7.9.2  使用顯式緩存的好處   180
7.10  持久化應用狀態   180
7.10.1  原子狀態   181
7.10.2  保存模型狀態   181
7.10.3  保存模型狀態的代碼   182
7.10.4  啟動時加載模型狀態   183
7.10.5  加載模型狀態的代碼   184
7.11  BehaviorSubject和存儲   184
7.12  簡單的SharedPreferencesStore   185
7.13  本章小結   186
7.13.1 作為事實來源的模型   187
7.13.2  反應式架構的其他部分   187

第8章  使用視圖模型進行開發   189
8.1  視圖模型和視圖   189
8.2  示例:井字游戲   190
8.3  繪制游戲網格   191
8.3.1  draw函數   192
8.3.2  嘗試使用具有硬編碼值的視圖   193
8.4  使其具有交互性   194
8.4.1  反應式處理鏈   195
8.4.2  網格坐標解析代碼   195
8.4.3  解析網格位置的代碼   196
8.4.4  擴展的圖結構   197
8.5  事件與反應狀態   198
8.5.1  劃清事件和狀態之間的界限   198
8.5.2  不同observable的示例   199
8.6  不可變數據和游戲網格   200
8.6.1  復制網格   201
8.6.2  更改GameGrid   201
8.6.3  Java中的變量引用和原始數據類型   201
8.6.4  GameGrid類型和setter函數   203
8.7  添加交互代碼   203
8.7.1  準備工作   203
8.7.2  基於事件更新GameGrid   204
8.7.3  包含.withLatestFrom的循環圖   205
8.8  將邏輯封裝到視圖模型中   210
8.9  使用click事件進行坐標處理   212
8.10  更改回合   213
8.10.1  連接多個視圖模型輸出   214
8.10.2  改進的網格數據類型   215
8.10.3  更新playerInTurn-Observable   215
8.10.4  在圖中插入玩家回合   216
8.10.5  GameState結構   217
8.11  過濾非法動作   219
8.11.1  阻止非空圖塊   219
8.11.2  使用pair臨時捆綁數據   220
8.11.3  向GameViewModel添加過濾   220
8.12  獲勝條件   221
8.12.1  確定GameState的代碼   222
8.12.2  生成getWinner函數   222
8.12.3  在UI中顯示GameState   223
8.12.4  視圖綁定代碼   224
8.12.5  游戲結束後過濾所有動作   225
8.13  還有一件事:重新啟動游戲   225
8.14  本章小結   226

第9章  擴展現有的Rx應用   229
9.1  使用現有的反應代碼   229
9.2  四子棋游戲   230
9.3  更新網格尺寸和資源   230
9.3.1  資源和繪圖   231
9.3.2  黑色和紅色   231
9.3.3  放置標記   231
9.3.4  井字游戲反應圖   232
9.3.5  把井字游戲圖改為四子棋游戲圖   232
9.3.6  在四子棋游戲中放入標記   233
9.3.7  dropping函數的代碼   234
9.4  檢查有效動作   235
9.4.1  允許的動作   235
9.4.2  更新的事件處理鏈   237
9.4.3  回顧事件處理中的步驟   238
9.5  保存並加載游戲   240
9.6  創建模型   240
9.6.1  原始圖   241
9.6.2  將GameState移到模型中   241
9.6.3  GameModel代碼   242
9.7  共享模型   243
9.7.1  “保持簡單”的版本   243
9.7.2  擴展過於簡單的版本   244
9.7.3  更新反應方式   244
9.7.4  存儲和observable   246
9.8  加載游戲活動   247
9.9  PersistedGameStore   248
9.10  保存游戲   250
9.11  加載游戲   251
9.12  本章小結   252

第10章  測試反應代碼   253
10.1  反應式架構和測試   253
10.2  測試粒度   254
10.3  依賴項金字塔結構   254
10.3.1  測試的類型   255
10.3.2  應用中的外部因素   256
10.4  單元測試基礎   256
10.4.1  佈置、動作、斷言   256
10.4.2  什麽是測試   256
10.4.3  單元測試的代碼示例   256
10.5  測試反應鏈   257
10.5.1  為RxJava和Mockito設置測試   258
10.5.2  測試自定義的observable   258
10.5.3  介紹test subscriber   258
10.6  TestObservable類   259
10.6.1  檢查終止   259
10.6.2  檢查輸出的值   259
10.6.3  測試observable的列表排序   259
10.6.4  測試異步代碼   260
10.7  同步或者異步   260
10.7.1  嘗試測試一個行為異常的函數   260
10.7.2  測試單線程RxJava函數   261
10.8  編寫視圖模型的測試   264
10.8.1  四子棋游戲視圖模型   264
10.8.2  GameViewModel輸入的作用   264
10.9  選擇測試什麽   265
10.10  測試GameViewModel初始狀態   266
10.10.1  設置測試用例   266
10.10.2  第一個視圖模型測試用例   267
10.11  測試部分observable鏈   268
10.11.1  提取鏈   269
10.11.2  作為靜態函數的部分反應鏈   269
10.12  測試四子棋游戲放置邏輯   270
10.12.1  放置邏輯的測試用例   270
10.12.2  模擬依賴項   271
10.13  本章小結   272

第Ⅲ部分  高級RxJava架構
第11章  高級架構聊天客戶端1   275
11.1  使用WebSocket的聊天客戶端   275
11.2  如何傳輸消息   276
11.3  WebSocket   276
11.4  作為廣播者的WebSocket   277
11.5  連接到服務器   278
11.6  ChatMessage結構   280
11.7  發送ChatMessage   281
11.7.1  消息數據流   281
11.7.2  發送ChatMessage時的錯誤   282
11.7.3  運行應用   282
11.8  將監聽器包裝到observable中   283
11.8.1  包含Observable.create的監聽器   283
11.8.2  取消訂閱時釋放監聽器   283
11.9  基本UI   285
11.10  顯示消息   287
11.10.1  繪制視圖模型和視圖   287
11.10.2  創建ArrayAdapter   287
11.11  視圖模型   288
11.11.1  設置   289
11.11.2  初步實現   289
11.12  累加ChatMessage   290
11.13  整合消息處理   291
11.14  使用視圖模型中的值   293
11.15  視圖模型生命周期   293
11.16  創建視圖模型生命周期   294
11.16.1  使視圖模型瞭解其訂閱   294
11.16.2  Subscribe和Unsubscribe方法   295
11.17  本章小結   295
11.17.1  取消訂閱時的清理   296
11.17.2  視圖模型和架構   296

第12章  高級架構聊天客戶端2   297
12.1  視圖模型、存儲和模型   297
12.1.1  聊天客戶端概述   297
12.1.2  聊天客戶端架構   298
12.2  消息掛起狀態   299
12.3  處理狀態更新   300
12.4  作為aggregator的存儲   300
12.4.1  aggregator是存儲嗎   301
12.4.2  將aggregator切換到存儲   301
12.5  存儲的代碼   302
12.5.1  解析器的故事   303
12.5.2  最初的存儲實現   303
12.5.3  更新的視圖模型   303
12.5.4  更新的Activity代碼   304
12.6  實現掛起的消息   307
12.6.1  呈現掛起狀態   307
12.6.2  聊天消息format函數   308
12.7  用確認的消息替換掛起的消息   308
12.7.1  消息ID   309
12.7.2  消息更新流程   309
12.8  更新存儲代碼   310
12.8.1  使用映射避免重復   310
12.8.2  對映射進行編碼   311
12.8.3  副作用:消息順序   311
12.9  掛起狀態的處理代碼   311
12.10  模型   314
12.10.1  作為容器的數據層   314
12.10.2  簡化的高級架構   315
12.10.3  頻譜中的模型   315
12.11  模型的代碼   316
12.12  模型生命周期   317
12.13  單例模塊   318
12.14  用於生產的Android工具   320
12.14.1  Dagger   320
12.14.2  Subject   320
12.14.3  意外終止observable   320
12.14.4  聲明錯誤處理程序   321
12.14.5  日誌記錄和線程   321
12.14.6  存儲   321
12.15  本章小結   321
12.15.1  視圖模型   321
12.15.2  模型   322
12.15.3  表示器   322

第13章  Rx轉換   323
13.1  狀態之間的轉換   323
13.1.1  “即發即棄”策略   324
13.1.2  小故障   324
13.2  應該是怎樣的   325
13.2.1  更復雜的場景   326
13.2.2  UI狀態不是真或假   326
13.3  使用一個數字的動畫進度   327
13.4  反應參數化   328
13.5  示例:風扇小部件   329
13.6  設置子視圖的轉換   330
13.6.1  每個子視圖的總旋轉角度   330
13.6.2  設置旋轉中心   331
13.7  使用RxJava和Android進行動畫處理   333
13.8  更改FanView的代碼   334
13.9  視圖模型   336
13.9.1  連接視圖模型和視圖   336
13.9.2  視圖模型輸入和輸出   336
13.10  視圖模型邏輯   337
13.11  在視圖模型中激活參數化的值   339
13.12  animateTo操作符   340
13.13  Android上的animateTo操作符   342
13.14  添加暗淡的背景   343
13.15  本章小結   345
13.15.1  動畫和視圖模型   345
13.15.2  接下來的內容   346

第14章  創建地圖客戶端   347
14.1  地圖示例   347
14.1.1  為什麽使用地圖   347
14.1.2  地圖繪制基礎   348
14.2  地圖圖塊入門   348
14.2.1  通向世界的窗口   348
14.2.2  合並網格和窗口   349
14.2.3  繪制空圖塊需要哪些數據   350
14.3  創建初始視圖模型   351
14.4  根據縮放級別計算圖塊   352
14.4.1  計算縮放級別的所有圖塊   353
14.4.2  移動地圖圖塊   354
14.4.3  地圖偏移量   354
14.5  使用偏移量移動圖塊   355
14.6  拖動地圖   356
14.6.1  拖動和反應   357
14.6.2  使用xyMovementEvents更新偏移量   358
14.7  到目前為止的代碼   359
14.8  Viewport和隱藏圖塊   359
14.8.1  計算可見圖塊的矩形   360
14.8.2  插入可見的圖塊   361
14.9  加載地圖圖塊   361
14.9.1  下載地圖圖像   362
14.9.2  地圖圖塊加載程序   363
14.10  添加縮放級別控件   364
14.10.1  圖   364
14.10.2  代碼   365
14.10.3  縮放級別地圖偏移量限制   365
14.11  添加對地圖坐標的支持   365
14.11.1  數學知識   366
14.11.2  構建lat/lng地圖中心的代碼   367
14.12  本章小結   368
附錄A  Android開發教程   371