RxJava2 和 Retrofit2 的封裝和使用

根據 RxJava2 和 Retrofit2 進行的封裝骗绕,進行網絡請求更加方便圆雁。

demo下載地址:https://github.com/sundevin/rxjava2_retrofit2

目前實現:

1, 統一風格的接口
2, 不統一風格的接口
3, 內存泄漏問題
4, 請求過程中 ProgressDialog
5, 自定義證書的 Https 的封裝
6, 使用 okHttp 進行下載時進度回調的封裝

后面將實現帶進度回調的上傳功能。

針對 Restful 風格的接口可以直接指定泛型嗜暴;
內部增加了 StringConverterFactory耸棒,非 Restful 風格的接口(如一些第三方接口的數據)可以直接獲取到 String,自行進行數據解析;
網絡請求過程中可以綁定到當前的 Activity, Activity 關閉的時候會主動停止請求橡淆,避免內存泄漏。也可決定是否顯示 ProgressDialog母赵;
數據請求前后可以打印 request 和 response 信息逸爵,更直觀的進行接口調試;
對 https 進行了封裝凹嘲,只需要指定自簽名證書即可师倔。
在使用 okHttp 請求的時候,支持進度回調和取消下載周蹭。

初始配置

1,項目依賴
    compile 'io.reactivex.rxjava2:rxjava:2.0.7'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

    compile 'com.squareup.retrofit2:retrofit:2.2.0'
    compile 'com.squareup.retrofit2:converter-gson:2.2.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'

    compile 'com.trello.rxlifecycle2:rxlifecycle:2.0.1'
    // If you want to bind to Android-specific lifecycles
    compile 'com.trello.rxlifecycle2:rxlifecycle-android:2.0.1'
    // If you want pre-written Activities and Fragments you can subclass as providers
    compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.0.1'

運行時可能會有依賴錯誤趋艘,在 androidTestCompile 配置如下即可解決

    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.google.code.findbugs', module: 'jsr305'
    })
2,OkHttp 配置
        CustomHttpsTrust customHttpsTrust = new CustomHttpsTrust(CertificateManager.trustedCertificatesInputStream());

        okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
                .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
                .addInterceptor(new HeaderInterceptor()) //添加 header
                .addInterceptor(new LoggingInterceptor())  //請求信息的打印 ,可在 release 時關閉
                .sslSocketFactory(customHttpsTrust.sSLSocketFactory, customHttpsTrust.x509TrustManager)// https 配置
                .build();
3,Retrofit 配置
       static {
        retrofit = new Retrofit.Builder()
                .baseUrl(ApiService.BASE_URL)//配置 baseUrl
                .client(OkHttpHelper.getClient())
                .addConverterFactory(StringConverterFactory.create()) //String 轉換
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .validateEagerly(true)
                .build();
    }

Restful 接口

以 demo 中后臺返回的標準數據為例凶朗,
resultobj 時:

{
      "state":1,
      "msg":"success",
      "result":{}
  }

result 為數組時:

{
      "state":1,
      "msg":"success",
      "result":[]
  }

其中 state 為1時表示業(yè)務處理成功瓷胧,數據正確。反之業(yè)務處理有誤棚愤,用msg 進行提示搓萧。
則建立 Entity 如下:

public class HttpResponseResult<T> {

    private static final int SUCCESS_STATUS = 1;
    private String msg;
    private Integer state;
    private T result;

    public boolean isSuccess() {
        return state != null && state == SUCCESS_STATUS;
    }

    public String getMsg() {
        return msg;
    }

    public Integer getState() {
        return state;
    }

    public T getResult() {
        return result;
    }

    @Override
    public String toString() {
        return "HttpResponse{" +
                "msg='" + msg + '\'' +
                ", state=" + state +
                ", result=" + result +
                '}';
    }
}

Object的請求:

    /**
     *  post test
     * @param map
     * @return
     */
    @POST("/muses-rest/java/rest/viewlogistics/"+CHANEL)
    Observable<HttpResponseResult<LogisticsInfo>> getLogisticsInfo(@Body Map<String,Object> map);

開始請求:

 Map<String, Object> map = new HashMap<>();
 map.put("logisticsid", 20);
 map.put("logisticsno", "1000817443587");
 ServiceManager
         .getApiService()
   .getLogisticsInfo(map)
                        .compose(MainActivity.this.<HttpRespResult<LogisticsInfo>>bindToLifecycle())
                        .compose(TransformerHelper.<LogisticsInfo>transformer())
                        .compose(new DialogTransformer(MainActivity.this).<HttpRespResult<LogisticsInfo>>showDialog())
                        .subscribe(new CommonObserver<LogisticsInfo>() {
             @Override
             protected void onSuccess(LogisticsInfo logisticsInfo) {
                 Logger.e(logisticsInfo.toString());
             }
         });

List的請求:

    @POST("/muses-rest/java/rest/viewlogistics/"+CHANEL)
    Observable<HttpResponseResult<LogisticsInfo>> getLogisticsInfo(@Body Map<String,Object> map);

開始請求:

ServiceManager
        .getApiService()
        .testGet2()
      .compose(MainActivity.this.<HttpRespResult<List<String>>>bindToLifecycle())
                        .compose(TransformerHelper.<List<String>>transformer())
                        .compose(new DialogTransformer(MainActivity.this).<HttpRespResult<List<String>>>showDialog())
                        .subscribe(new CommonObserver<List<String>>() {
            @Override
            protected void onSuccess(List<String> stringList) {
                String[] str = stringList.toArray(new String[stringList.size()]);
                Logger.e(Arrays.toString(str));
            }
        });

注意三個 compose 操作符的順序不要亂了,否則會出現異常遇八。
其中

 .compose(MainActivity.this.<HttpResponseResult<List<String>>>bindToLifecycle())

是與當前的 Activity 進行綁定矛绘,Activity 需要繼承 RxAppCompatActivity 或者 RxActivity ,如果已有自己的 BaseActivity,則讓 BaseActivity 去繼承即可刃永。Fragment類似货矮。

.compose(TransformerHelper.<List<String>>transformer())

是對請求結果進行處理,即從 HttpResponseResult 取出 T斯够。

 .compose(new DialogTransformer(MainActivity.this).<List<String>>showDialog())

是操作 ProgressDialog 的囚玫,其生命周期會伴隨整個請求,不需要時可以不加读规。

一般在請求成功后會進行數據處理抓督,而失敗時則進行 Toast 提示用戶,CommonObserver中已經對錯誤進行了處理束亏,自動彈出 Toast铃在,如果不需要彈出 Toast ,重寫 CommonObserveronFailed(HttpResponseException responseException) 方法即可。如果需要針對不同的業(yè)務邏輯錯誤進行不同的處理定铜,則使用 responseException.getStatus() 得到錯誤碼進行處理即可阳液。

非 Restful 接口

由于非 Restful 接口用的可能比較少,所以沒對其進行整理揣炕,只提供了一個實現帘皿,當然,如果項目中非 Restful 接口用的比較多的話還是封裝一下比較好畸陡。

ServiceManager
       .getApiService()
       .testGet1()
       .compose(SchedulerTransformer.<String>transformer())//線程轉換
       .compose(MainActivity.this.<String>bindToLifecycle())//綁定生命周期鹰溜,防止內存泄露
       .compose(new DialogTransformer(MainActivity.this).<String>transformer())//progressDialog
       .subscribe(new Observer<String>() {
           @Override
           public void onSubscribe(Disposable d) {
           }
           @Override
           public void onNext(String s) {
               Logger.e(s);
           }
           @Override
           public void onError(Throwable e) {
               Logger.e(e.toString());
           }
           @Override
           public void onComplete() {
           }
       });

下載操作

 final DownloadHelper downloadHelper = new DownloadHelper(url, dirPath, fileName);

        downloadHelper.downloadFile(new DownloadListener() {
            @Override
            public void update(long bytesRead, long contentLength) {
                Logger.e("----bytesRead=" + bytesRead);
                Logger.e("----contentLength=" + contentLength);
                progressDialog.setProgress((int) ((100 * bytesRead) / contentLength));
            }

            @Override
            public void onSuccess(File file) {
                progressDialog.cancel();
                Logger.e(file.getAbsolutePath() + "----" + file.length());
            }

            @Override
            public void onFailure(Throwable t) {
                progressDialog.cancel();
                Logger.e("----" + t.toString());
            }
        });

取消下載

  downloadHelper.cancelDownload();
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市丁恭,隨后出現的幾起案子曹动,更是在濱河造成了極大的恐慌,老刑警劉巖牲览,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仁期,死亡現場離奇詭異,居然都是意外死亡竭恬,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門熬的,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痊硕,“玉大人,你說我怎么就攤上這事押框〔沓瘢” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵橡伞,是天一觀的道長盒揉。 經常有香客問我,道長兑徘,這世上最難降的妖魔是什么刚盈? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮挂脑,結果婚禮上藕漱,老公的妹妹穿的比我還像新娘。我一直安慰自己崭闲,他們只是感情好肋联,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著刁俭,像睡著了一般橄仍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天侮繁,我揣著相機與錄音虑粥,去河邊找鬼。 笑死鼎天,一個胖子當著我的面吹牛舀奶,可吹牛的內容都是我干的。 我是一名探鬼主播斋射,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼育勺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了罗岖?” 一聲冷哼從身側響起涧至,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎桑包,沒想到半個月后南蓬,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡哑了,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年赘方,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弱左。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡窄陡,死狀恐怖,靈堂內的尸體忽然破棺而出拆火,到底是詐尸還是另有隱情跳夭,我是刑警寧澤,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布们镜,位于F島的核電站币叹,受9級特大地震影響,放射性物質發(fā)生泄漏模狭。R本人自食惡果不足惜颈抚,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嚼鹉。 院中可真熱鬧邪意,春花似錦、人聲如沸反砌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宴树。三九已至策菜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背又憨。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工翠霍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蠢莺。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓寒匙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親躏将。 傳聞我的和親對象是個殘疾皇子锄弱,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,334評論 25 707
  • 前言RxJava和Retrofit也火了一段時間了,不過最近一直在學習ReactNative和Node相關的姿勢祸憋,...
    AFinalStone閱讀 556評論 0 0
  • 前言 RxJava和Retrofit也火了一段時間了会宪,不過最近一直在學習ReactNative和Node相關的姿勢...
    流水潺湲閱讀 1,226評論 3 6
  • 這夜的黑 榨出思戀的液汁 滲入千瘡百孔的干涸 滿山的紅葉 可是你微笑的音符 捎來春天的潮汐 你涉水而去 沒留下一瓣...
    荒山小調閱讀 205評論 0 0
  • 1. 感恩媽媽為我們準備素食,讓全家人吃素蚯窥。 2. 感恩朋友請吃夜宵掸鹅。 3. 感恩媽媽陪我在大年初一一起去參加發(fā)展...
    詩羚閱讀 306評論 0 1