日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Retrofit与RXJava整合

發(fā)布時間:2024/7/23 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Retrofit与RXJava整合 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Retrofit 除了提供了傳統(tǒng)的 Callback 形式的 API,還有 RxJava 版本的 Observable 形式 API。下面我用對比的方式來介紹 Retrofit 的 RxJava 版 API 和傳統(tǒng)版本的區(qū)別。

以獲取一個 User 對象的接口作為例子。使用Retrofit 的傳統(tǒng) API,你可以用這樣的方式來定義請求:

@GET("/user") public void getUser(@Query("userId") String userId, Callback<User> callback);

在程序的構(gòu)建過程中, Retrofit 會把自動把方法實現(xiàn)并生成代碼,然后開發(fā)者就可以利用下面的方法來獲取特定用戶并處理響應:

getUser(userId, new Callback<User>() {@Overridepublic void success(User user) {userView.setUser(user);}@Overridepublic 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>() {@Overridepublic void onNext(User user) {userView.setUser(user);}@Overridepublic void onCompleted() {}@Overridepublic void onError(Throwable error) {// Error handling...}});

看到區(qū)別了嗎?

當 RxJava 形式的時候,Retrofit 把請求封裝進 Observable ,在請求結(jié)束后調(diào)用 onNext() 或在請求失敗后調(diào)用 onError()。

對比來看, Callback 形式和 Observable 形式長得不太一樣,但本質(zhì)都差不多,而且在細節(jié)上 Observable 形式似乎還比 Callback 形式要差點。那 Retrofit 為什么還要提供 RxJava 的支持呢?

因為它好用啊!從這個例子看不出來是因為這只是最簡單的情況。而一旦情景復雜起來, Callback 形式馬上就會開始讓人頭疼。比如:

假設(shè)這么一種情況:你的程序取到的 User 并不應該直接顯示,而是需要先與數(shù)據(jù)庫中的數(shù)據(jù)進行比對和修正后再顯示。使用 Callback 方式大概可以這么寫:

getUser(userId, new Callback<User>() {@Overridepublic void success(User user) {processUser(user); // 嘗試修正 User 數(shù)據(jù)userView.setUser(user);}@Overridepublic void failure(RetrofitError error) {// Error handling...} };

有問題嗎?

很簡便,但不要這樣做。為什么?因為這樣做會影響性能。數(shù)據(jù)庫的操作很重,一次讀寫操作花費 10~20ms 是很常見的,這樣的耗時很容易造成界面的卡頓。所以通常情況下,如果可以的話一定要避免在主線程中處理數(shù)據(jù)庫。所以為了提升性能,這段代碼可以優(yōu)化一下:

getUser(userId, new Callback<User>() {@Overridepublic void success(User user) {new Thread() {@Overridepublic void run() {processUser(user); // 嘗試修正 User 數(shù)據(jù)runOnUiThread(new Runnable() { // 切回 UI 線程@Overridepublic void run() {userView.setUser(user);}});}).start();}@Overridepublic void failure(RetrofitError error) {// Error handling...} };

性能問題解決,但……這代碼實在是太亂了,迷之縮進啊!雜亂的代碼往往不僅僅是美觀問題,因為代碼越亂往往就越難讀懂,而如果項目中充斥著雜亂的代碼,無疑會降低代碼的可讀性,造成團隊開發(fā)效率的降低和出錯率的升高。

這時候,如果用 RxJava 的形式,就好辦多了。 RxJava 形式的代碼是這樣的:

getUser(userId).doOnNext(new Action1<User>() {@Overridepublic void call(User user) {processUser(user);}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<User>() {@Overridepublic void onNext(User user) {userView.setUser(user);}@Overridepublic void onCompleted() {}@Overridepublic void onError(Throwable error) {// Error handling...}});

其中

doOnNext()的執(zhí)行在onNext()之前,對數(shù)據(jù)進行相關(guān)處理。doOnNext在哪一個線程處理,暫時不明。

參考鏈接

RxJava操作符doOnNext - 享受技術(shù)帶來的快樂! - 博客頻道 - CSDN.NET

Rxjava中的doOnNext的作用和在哪里執(zhí)行 - u010746364的博客 - 博客頻道 - CSDN.NET

后臺代碼和前臺代碼全都寫在一條鏈中,明顯清晰了很多。

再舉一個例子:假設(shè) /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>() {@Overridepublic void success(String token) {getUser(token, userId, new Callback<User>() {@Overridepublic void success(User user) {userView.setUser(user);}@Overridepublic void failure(RetrofitError error) {// Error handling...}};}@Overridepublic 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>>() {@Overridepublic Observable<User> onNext(String token) {return getUser(token, userId);}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<User>() {@Overridepublic void onNext(User user) {userView.setUser(user);}@Overridepublic void onCompleted() {}@Overridepublic void onError(Throwable error) {// Error handling...}});

用一個 flatMap() 就搞定了邏輯,依然是一條鏈。看著就很爽,是吧?

RxJava配合Retrofit2.0使用

新的Retrofit2.0簡直就是設(shè)計模式的教科書典范,同時對Rx的支持也更加友好,本例子為查詢ip獲取地理信息,并過濾掉失敗信息

//使用Rxjava配合Retrofit解析json數(shù)據(jù),注意這里全是電腦運行的,沒有分開線程訂閱 public static void main(String[] args) throws Exception{ OkHttpClient client = new OkHttpClient(); client.interceptors().add(new LoggingInterceptor());//log for okhttpRetrofit retrofit = new Retrofit.Builder().baseUrl(IPService.END).client(client).addConverterFactory(GsonConverterFactory.create())//對Response進行adapter轉(zhuǎn)換.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//對轉(zhuǎn)換后的數(shù)據(jù)進行再包裝.build();retrofit.create(IPService.class)//動態(tài)代理生成class//直接操作json數(shù)據(jù),這里可不是一個好的習慣,真正應該是DTO對象的.getIPInfo("58.19.239.11").filter(jsonObject -> jsonObject.get("code").getAsInt()==0)//轉(zhuǎn)換數(shù)據(jù)類型.map(jsonObject1 -> jsonObject1.get("data"))//輸出結(jié)果.subscribe(System.out::println); }//retrofit定義的接口 interface IPService {String END = "http://ip.taobao.com";//建議寫成dto對象,博主只是為了演示filter就把這里JsonObject了@GET("/service/getIpInfo.php") Observable<JsonObject> getIPInfo(@Query("ip") String ip); }/** * Retrofit2.0已經(jīng)把網(wǎng)絡部分剝離了,所以需要自己實現(xiàn)Log */ static class LoggingInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException {Request request = chain.request();long t1 = System.nanoTime();System.out.println(String.format("Sending request %s on %s%n%s", request.url(), chain.connection(),request.headers()));Response response = chain.proceed(request);long t2 = System.nanoTime();System.out.println(String.format("Received response for %s in %.1fms%n%s", response.request().url(),(t2 - t1) / 1e6d, response.headers()));return response; }

源代碼

rengwuxian RxJava Samples

參考鏈接

給 Android 開發(fā)者的 RxJava 詳解

函數(shù)式編程RxJava操作實例 - 簡書

總結(jié)

以上是生活随笔為你收集整理的Retrofit与RXJava整合的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产人澡人澡澡澡人碰视频 | 国产三级直播 | 成人做爰66片免费看网站 | 奇米888一区二区三区 | 日本一区二区视频 | 亚洲作爱网| 国产精品视频你懂的 | 爱啪啪av | 999xxxxx| 少妇一级淫免费放 | 欧美一区二区日韩一区二区 | 日本人体视频 | 日日爱886| 久久一级大片 | 黄色免费网站观看 | 波多野吉衣伦理片 | 台湾无码一区二区 | 一本一道波多野结衣一区二区 | 高清成人免费视频 | 艳妇臀荡乳欲伦交换在线播放 | 国内av网站 | 国产一区免费视频 | 欧美极品第一页 | 91一区二区三区在线观看 | 成人黄性视频 | 亚洲国产毛片aaaaa无费看 | 丝袜高跟av | 97在线观看视频免费 | 久久精品国产亚洲AV黑人 | 香蕉国产999 | 亚洲综合小说 | 亚洲精品网站在线观看 | 亚洲无av | 九九亚洲视频 | 91视频88av| 日韩精品视频中文字幕 | 夜夜躁很很躁日日躁麻豆 | 国产草草影院 | 粗大的内捧猛烈进出 | 亚洲综合图片一区 | 超碰在线免费看 | 日韩h在线观看 | 国产99re| 国产毛片毛片毛片毛片毛片毛片 | 午夜在线精品偷拍 | 尤物在线精品 | 国精产品一区一区三区免费视频 | 夜夜操免费视频 | 五月六月婷婷 | 欧美xxxx18| 黄色录像a级片 | 免费在线观看网址入口 | 免费大片黄在线观看视频网站 | 国产精品综合在线 | 成人福利视频在线 | 人妻一区在线 | 国产美女久久久久 | 亚洲人一区二区三区 | 蜜乳av 懂色av 粉嫩av | 国产视频九色蝌蚪 | 天天综合中文字幕 | 日日摸夜夜添夜夜添高潮喷水 | 国产suv一区二区 | 91精品久久久久久 | 免费一级淫片 | 51吃瓜网今日 | 悠悠色在线 | 91国产高清 | 欧美浓毛大泬视频 | 日韩一级免费看 | 欧美精品久久96人妻无码 | 黄视频在线免费 | 一个人在线观看免费视频www | 日韩不卡免费 | 成人影片在线播放 | 亚洲啊啊啊啊啊 | 亚洲精品乱码久久久久久蜜桃欧美 | 国产精品一级片 | 一区二区三区少妇 | 男人添女人囗交视频 | 欧美a v在线播放 | 欧美高清在线视频 | 亚洲狠狠干| 制服av在线| 日本成人激情 | 韩国三级国产 | 人妻少妇精品中文字幕av蜜桃 | 毛片视屏| 国产美女操 | 我爱avav色aⅴ爱avav | 国产91白丝在一线播放 | 无码精品一区二区三区在线 | 午夜av在线免费观看 | 18视频网站在线观看 | 亚洲夜夜夜| 国产大学生视频 | 欧美黄色小视频 | 性高潮久久久久久 | 激情 小说 亚洲 图片 伦 |