天天看點

Retrofit2結合RxJava2簡單處理嵌套請求(flatMap)

gradle

compile 'io.reactivex:rxjava:1.2.0'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'      

(素材來源于http://www.jianshu.com/p/1fb294ec7e3b)

1重請求(也已經和正常的retrofit2請求完全不一樣了,retrofit2被完全地封裝到了rxjava2裡)

首先接口的傳回值(已經大不一樣,傳回的是rxjava2中的Observable,如果是retrofit2的話傳回的應該是retrofit2.Call<UserInfo>)

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

具體使用

(通過接口擷取Observable對象,doOnNext等同于寫在onCompleted裡)

(此外注意retrofit2在初始化的時候還要加上一行.addCallAdapterFactory(RxJavaCallAdapterFactory.create()))

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) {
                //請求成功
            }
        });      

2重請求

//登入,擷取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) {
            //請求失敗
        }
    });                

上面兩個方法寫在一個接口裡了。

這裡看起來就像是隻有一個請求,尤其是retrofit2黨更會不明是以。

其實他是先用賬号密碼登入了,再傳回一個token,再用這個token請求user,再傳回user對象。

顯示傳回了Observer<String>,再通過那個func1函數把資料源從String轉化成了User。

url的變化流程是:賬号密碼-》token

請求的流程是:給賬号密碼-》拿token-》給token-》拿User對象。

接下來就是這個組合架構的威力了,不需要你寫多個rxjava2的訂閱了,把你所有的操作封裝成一次請求(隻是看起來)。你隻需要合理提供轉化多個url就可以了。