【Android】RxJava + Retrofit完成網絡請求

RxJava + Retrofit

前言

本文基于RxJava、Retrofit的使用,若是對RxJava或Retrofit還不了解的簡友可以先了解RxJava、Retrofit的用法再來看這篇文章。
在這片文章之前分別單獨介紹過Rxjava以及Retrofit的使用:
Android Retrofit 2.0 的使用
Android RxJava的使用(一)基本用法
(以及后面的幾篇,就不一一列出了)

使用

在了解了RxJava和Retrofit分別的用法后,RxJava、Retrofit的搭配使用也就不再話下了。
先看看使用Retrofit完成一次網絡請求是怎樣的

  • 單獨使用Retrofit
    1、先寫一個service
interface MyService {
    @GET("user/login" )
    Call<UserInfo> login(
            @Query("username") String username,
            @Query("password") String password
    );
}

2、獲取Call執行網絡請求

        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(BASE_URL)
                .build();
        MyService service = retrofit.create(MyService.class);

        Call<UserInfo> call = service.login("1111", "ssss");
        call.enqueue(new Callback<UserInfo>() {
            @Override
            public void onResponse(Call<UserInfo> call, Response<UserInfo> response) {
                //請求成功操作
            }
            @Override
            public void onFailure(Call<UserInfo> call, Throwable t) {
                //請求失敗操作
            }
        });

以上是Retrofit單獨使用時的做法。那Retrofit與RxJava結合是怎樣使用的?下面就來說說這篇文章的重點。

  • RxJava + Retrofit完成網絡請求
    1、添加依賴。前四個分別是RxJava、RxAndroid、Retrofit以及Gson的庫,最后那個才是新加入的,RxJava + Retrofit的使用需要用到最后那個包。
    compile 'io.reactivex:rxjava:x.y.z'
    compile 'io.reactivex:rxandroid:1.0.1'
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'

注意:最后三個包的版本號必須一樣,這里用的是2.0.2。
2、寫一個登錄的service

interface MyService {
    @GET("user/login" )
    Observable<UserInfo> login(
            @Query("username") String username,
            @Query("password") String password
    );
}

相比之前的service,這里getNews方法的返回值是Observable類型。Observable...是不是覺得很熟悉,這貨不就是之前在RxJava使用到的被監聽者?
3、使用Observable完成一個網絡請求,登錄成功后保存數據到本地。

        Retrofit retrofit = new Retrofit.Builder()
              .addConverterFactory(GsonConverterFactory.create())
              .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//新的配置
              .baseUrl(BASE_URL)
              .build();
        MyService service = retrofit.create(MyService.class);

        service.login(phone, password)               //獲取Observable對象
                .subscribeOn(Schedulers.newThread())//請求在新的線程中執行
                .observeOn(Schedulers.io())         //請求完成后在io線程中執行
                .doOnNext(new Action1<UserInfo>() {
                    @Override
                    public void call(UserInfo userInfo) {
                        saveUserInfo(userInfo);//保存用戶信息到本地
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//最后在主線程中執行
                .subscribe(new Subscriber<UserInfo>() {
                    @Override
                    public void onCompleted() {
                        
                    }

                    @Override
                    public void onError(Throwable e) {
                        //請求失敗
                    }

                    @Override
                    public void onNext(UserInfo userInfo) {
                        //請求成功
                    }
                });

RxJava + Retrofit 形式的時候,Retrofit 把請求封裝進 Observable ,在請求結束后調用 onNext() 或在請求失敗后調用 onError()。
可以看到,調用了service的login方法后得到Observable對象,在新的線程中執行網絡請求,請求成功后切換到io線程執行保存用戶信息的動作,最后再切換到主線程執行請求失敗onError()、請求成功onNext()。整體的邏輯十分清晰都在一條鏈中,就算還有別的要求還可以往里面添加,絲毫不影響代碼的簡潔。(終于舉了一個有實際意義的例子)

注意:retrofit的初始化加了一行代碼

addCallAdapterFactory(RxJavaCallAdapterFactory.create())
  • RxJava + Retrofit 進階
    在上面舉到登錄后保存用戶信息的例子,其實在做項目的時候,往往在登錄后得到的并不是用戶信息。一般登錄后會得到token,然后根據token去獲取用戶的信息。他們的步驟是這樣的:
    1、登錄
    2、獲取用戶信息(前提:登錄成功)
    可以看得出來,這是一個嵌套的結構...嵌套啊!!!天吶,最怕嵌套的結構了。
    使用RxJava + Retrofit來完成這樣的請求(借用拋物線的例子,稍微做了點改動)
 //登錄,獲取token
@GET("/login")
public Observable<String> login(   
    @Query("username") String username,
    @Query("password") String password);
 //根據token獲取用戶信息
@GET("/user")
public Observable<User> getUser(
    @Query("token") String token);
//..................................
service.login("11111", "22222")
    .flatMap(new Func1<String, Observable<User>>() {  //得到token后獲取用戶信息
        @Override
        public Observable<User> onNext(String token) {
            return service.getUser(token);
        })
    .subscribeOn(Schedulers.newThread())//請求在新的線程中執行請求
    .observeOn(Schedulers.io())         //請求完成后在io線程中執行
    .doOnNext(new Action1<User>() {      //保存用戶信息到本地
         @Override
         public void call(User userInfo) {
             saveUserInfo(userInfo);
         }
     })
    .observeOn(AndroidSchedulers.mainThread())//在主線程中執行
    .subscribe(new Observer<User>() {
        @Override
        public void onNext(User user) {
            //完成一次完整的登錄請求
            userView.setUser(user);
        }

        @Override
        public void onCompleted() {
  
        }

        @Override
        public void onError(Throwable error) {
            //請求失敗
        }
    });

通過一個flatMap()輕松完成一次嵌套的請求,而且邏輯十分清晰。so easy~~~

小結

RxJava的實用性從上面的兩個例子慢慢體現了出來,邏輯越是復雜,RxJava的優勢就越明顯。RxJava的使用就暫時介紹到這里吧,使用過程中遇到好用的再出來跟大家分享。

以上有錯誤之處感謝指出

參考:給 Android 開發者的 RxJava 詳解
(本文部分內容引用自該博客)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容