Retrofit和RxJava結合使用
使用Retrofit的時候就不得不提到RxJava,RxJava是一個基於觀察者模式的非同步實現。關於RxJava的入門學習,強烈推薦《給Android開發者的RxJava詳解》
正如上篇部落格所說,得益於Retrofit中靈活的Converter
,所以Retrofit對RxJava的支援也是異常的方便。我個人的感覺是,雖然RxJava的學習曲線比較陡峭,但是一旦學會,程式設計效率將大大提高。如果使用Retrofit而不用RxJava是非常可惜的,本文將闡述如何將Retrofit和RxJava進行結合。。
新增依賴
首先在build.gradle中加入依賴。為了使用gson解析json,還需要加入gson
converter-gson
兩個依賴,為了支援RxJava,還需要加入rxjava
和rxandroid
的庫,而銜接RxJava和Retrofit的就是adapter-rxjava
這個庫。
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.google.code.gson:gson:2.7'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'io.reactivex:rxandroid:1.2.0'
compile 'io.reactivex:rxjava:1.1.5'
定義請求介面
和之前的定義一樣,為了使用RxJava,需要把返回值改成Observable
型別即可:
public interface RetrofitImageUploadService {
@Multipart
@POST("EntranceGuardes/app/appOpen_pushdDataToApp.action")
Observable<UploadJsonResult> upload(@Part("userId") RequestBody description,
@Part MultipartBody.Part file);
}
這樣,upload
方法的返回值就是Observable<UploadJsonResult>
型別,可以想象到,這樣的返回值很容易和RxJava的資料流結合起來。
新增adapter-rxjava
和新增Gson支援一樣,只需要在Retrofit物件中加入addCallAdapterFactory
即可。addCallAdapterFactory(RxJavaCallAdapterFactory.create())
就可以使用RxJavaCallAdapterFactory
把Retrofit和RxJava結合起來。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://172.18.81.155:8080/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
RetrofitImageUploadService service = retrofit.create(RetrofitImageUploadService.class);
進行網路請求
這時呼叫service的upload方法,返回的結果就是Observable<UploadJsonResult>
,這樣就很容易與RxJava中豐富的運算子結合起來,方便各種處理。
Observable<UploadJsonResult> r=service.upload(description, body)
使用RxJava運算子
從上一步得到了Observable
型別的物件,我們如果需要對返回結果進行一些處理,只需要使用RxJava中的豐富的運算子就可以了。而RxJava中有對lambda表示式的支援,只要使用Java SE8就可以使用lambda表示式來簡寫其中的運算子。
service.upload(description, body)
.doOnNext(uploadJsonResult -> Log.d("upload image", uploadJsonResult.getMessage()))
.doOnError(throwable -> Log.d("upload image", "upload failed"));
上面兩句運算子使用了lambda表示式。doOnNext
表示如果請求成功,將在日誌中打印出uploadJsonResult.getMessage()
中得到的資料。doOnError
表示如果請求失敗,將在日誌中列印”upload failed”。除此之外,我們還可以增加執行緒的切換,比如使用observeOn(Schedulers)
讓網路請求在io執行緒中執行。
完整程式碼
public class UpLoadImage {
public interface RetrofitImageUploadService {
@Multipart
@POST("EntranceGuardes/app/appOpen_pushdDataToApp.action")
Observable<UploadJsonResult> upload(@Part("userId") RequestBody description,
@Part MultipartBody.Part file);
}
private String imagePath;
private String userId;
public UpLoadImage(String userId, String imagePath) {
this.imagePath = imagePath;
this.userId = userId;
}
public Observable<UploadJsonResult> upload() {
File file = new File(imagePath);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://172.18.81.155:8080/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
RetrofitImageUploadService service = retrofit.create(RetrofitImageUploadService.class);
RequestBody requestFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile);
RequestBody description = RequestBody.create(MediaType.parse("text/plain"), userId);
return service.upload(description, body)
.doOnNext(uploadJsonResult -> Log.d("upload image", uploadJsonResult.getMessage()))
.doOnError(throwable -> Log.d("upload image", "upload failed"));
}
}