1. 程式人生 > >Retrofit+RxJava處理網路請求

Retrofit+RxJava處理網路請求

Retrofit的基本用法在上一節已經介紹過了接下來我們介紹下Retrofit+RxJava的組合使用不了解Retrofit的用法的可以先看看我上篇部落格的介紹
Restrofit簡單入門
那如果不瞭解RxJava的我會在後續的課程中對RxJava進行介紹接下來我們就介紹 Retrofit+RxJava的簡單應用

1.gradle環境配置

程式碼如下

    compile 'io.reactivex.rxjava2:rxjava:2.0.0-RC1'//RxJava依賴包
    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'//Retrofit2所需要的包
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'//ConverterFactory的Gson依賴包 compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'//CallAdapterFactory的Rx依賴包 compile 'com.squareup.retrofit2:converter-scalars:2.0.0-beta4'//ConverterFactory的String依賴包

當我們配置完這些後執行專案可能會發生一個錯誤錯誤內容如下

Error:Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/rxjava.properties
    File1: C:\Users
\Administrator\.gradle\caches\modules-2\files-2.1\io.reactivex\rxjava\1.1.0\748f0546d5c3c27f1aef07270ffea0c45f0c42a4\rxjava-1.1.0.jar File2: C:\Users\Administrator\.gradle\caches\modules-2\files-2.1\io.reactivex.rxjava2\rxjava\2.0.0-RC1\3ee37bb825446a3bafac68a46f2397a8affd9b68\rxjava-2.0.0-RC1.jar

具體原因我也不是太清楚不過在我們的gradle的android目錄下新增如下程式碼問題就解決了

  packagingOptions {
        exclude 'META-INF/DEPENDENCIES.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/rxjava.properties'
        exclude 'META-INF/rxjava.PROPERTIES'
        exclude 'META-INF/RXJAVA.properties'
        exclude 'META-INF/RXJAVA.PROPERTIES'
        exclude 'META-INF/rxjava'
        exclude 'META-INF/RXJAVA'
    }

環境配置完成了接下來我們要做的是網路請求處理的那一套流程了

2.首先我們要有網路請求定義的介面跟方法

public interface HttpService {
        @POST("aaaa.do")
        @FormUrlEncoded
        Call<String> getString(@Field("currentVersion") String curVersion,
                               @Field("checkVersion") String checkVersion,
                               @Field("loginName") String loginName,
                               @Field("userName") String userName,
                               @Field("farmName") String farmName,
                               @Field("fw.excute.event") String eventId);

        @POST("1009.do")
        @FormUrlEncoded
        Observable<String> getAllVedioBy(@Field("currentVersion") String curVersion,
                                         @Field("checkVersion") String checkVersion,
                                         @Field("loginName") String loginName,
                                         @Field("userName") String userName,
                                         @Field("farmName") String farmName,
                                         @Field("fw.excute.event") String eventId);
    }

大家可以看到上面的getString方法是我們標準的Restrofit的介面定義方法而下面的的定義及處理是我們的RxJava的處理方式最主要的區別就是返回的不再是一個call物件而是一個Observable

3.接下來我們要寫基礎的網路訪問程式碼

  Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

再接下來處理網路訪問

HttpService apiService = retrofit.create(HttpService.class);
Observable<String> observable = apiService.getAllVedioBy("3.3", "4.8", "101111", "15111", "biubiu", "323A3A303A");
      observable.subscribeOn(Schedulers.io())
                .observeOn(Schedulers.immediate())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        boolean a = false;
                        int ss = 1;
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        String result = s.toLowerCase();
                    }
                });

建立retrofit 物件的方法跟上一節提到的一樣不同的是Observable observable = apiService.getAllVedioBy(…)這一段程式碼
其實原理很簡單restrofit將處理完的網路請求不再通過自己的call物件獲取了而是交給了Observable這樣的話Observable就持有了網路請求的結果。
再看下面的內容 observable.subscribeOn(Schedulers.io()).observeOn(Schedulers.immediate())這段話的意思是讓我們的觀察者在主執行緒也就是immediate這個執行緒而subscribeOn代表是被觀察者它的執行放在了io執行緒也就是單起個執行緒防止主執行緒卡死
.subscribe()意思是訂閱的意思觀察者訂閱被觀察者
new Subscriber() 這個相當於執行後的結果的回撥介面用於處理上面一系列流程處理的結果

經歷上面的過程我們的restrofit+rxjava的基本內容就處理完了但是回過頭來想想還有沒有可以改變的地方大多數app都是接收到的後臺資料為json資料要呈現在介面上一般需要將json轉換成物件然後通過物件獲取內容呈現在介面上那我們做如下修改這裡只處理結果內容

HttpService apiService = retrofit.create(HttpService.class);
Observable<String> observable = apiService.getAllVedioBy("3.3", "4.8", "101111", "15111", "biubiu", "323A3A303A");
      observable.subscribeOn(Schedulers.io())
                .observeOn(Schedulers.immediate())
                .map(new Func1<String, GetVersionResult>() {
                    @Override
                    public GetVersionResult call(String s) {
                        Gson gson = new Gson();
                        return gson.fromJson(s, GetVersionResult.class);
                    }
                })
                .subscribe(new Subscriber<GetVersionResult>() {
                    @Override
                    public void onCompleted() {
                        boolean a = false;
                        int ss = 1;
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(GetVersionResult errorString) {
                        String result = errorString.getReturn_sts();
                    }
                });

我們通過 .map將返回的結果集處理成了GetVersionResult 內容這樣我們下面的處理也就跟著Map的轉化轉換成了接收GetVersionResult引數的方法了。
最後借鴻洋大神的處理截圖看看大神是如何處理的

程式碼截圖