本文基於RxJava、Retrofit的使用,如果對RxJava或Retrofit還不瞭解的簡友能夠先了解RxJava、Retrofit的用法再來看這篇文章。
在這片文章以前分別單獨介紹過Rxjava以及Retrofit的使用:
Android Retrofit 2.0 的使用
Android RxJava的使用(一)基本用法
(以及後面的幾篇,就不一一列出了)java
在瞭解了RxJava和Retrofit分別的用法後,RxJava、Retrofit的搭配使用也就再也不話下了。
先看看使用Retrofit完成一次網絡請求是怎樣的react
一、先寫一個serviceandroid
interface MyService { @GET("user/login" ) Call<UserInfo> login( @Query("username") String username, @Query("password") String password ); }
二、獲取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結合是怎樣使用的?下面就來講說這篇文章的重點。ide
一、添加依賴。前四個分別是RxJava、RxAndroid、Retrofit以及Gson的庫,最後那個纔是新加入的,RxJava + Retrofit的使用須要用到最後那個包。post
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。
二、寫一個登陸的serviceui
interface MyService { @GET("user/login" ) Observable<UserInfo> login( @Query("username") String username, @Query("password") String password ); }
相比以前的service,這裏getNews方法的返回值是Observable類型。Observable...是否是以爲很熟悉,這貨不就是以前在RxJava使用到的被監聽者?
三、使用Observable完成一個網絡請求,登陸成功後保存數據到本地。spa
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())
在上面舉到登陸後保存用戶信息的例子,其實在作項目的時候,每每在登陸後獲得的並非用戶信息。通常登陸後會獲得token,而後根據token去獲取用戶的信息。他們的步驟是這樣的:
一、登陸
二、獲取用戶信息(前提:登陸成功)
能夠看得出來,這是一個嵌套的結構...嵌套啊!!!天吶,最怕嵌套的結構了。
使用RxJava + Retrofit來完成這樣的請求(借用拋物線的例子,稍微作了點改動)code
//登陸,獲取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 詳解(本文部份內容引用自該博客)