Retrofit2初嘗試(rxjava + okhttp3)
阿新 • • 發佈:2019-02-19
Retrofit2是一個網路載入相關的工具庫,和okhttp是同一個開發者,對於我們的開發還是十分有利的,這次就嘗試寫一個Retrofit2結合rxjava okhttp3的小demo:網路資料用的是聚合資料的票房排行
核心程式碼:
/** * 電影票房介面 * Created by Jing on 2016/5/24. */ public interface BoxOfficeApi { @GET("boxoffice/rank") Observable<ServiceResult<List<BoxOffice>>> getBoxOfficeData(@Query("key") String key, @Query("area") String area); }
介面中寫入具體地址,引數
返回引數為RxJava的Observable,當然Retrofit2還有很多可返回引數,如okhttp的Call,詳細可以參照資料中的解釋。
為了使用retrofit,我們建立一個全域性的管理類方便使用。
okhttp3的自帶日誌效果還是不錯的,比較直觀public class RetrofitManage { public static RetrofitManage retrofitManage; private Retrofit retrofit; public RetrofitManage(){ //OKHTTP攔截器,用於配置 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(loggingInterceptor) //日誌,可以配置 level 為 BASIC / HEADERS / BODY .retryOnConnectionFailure(true) .connectTimeout(15, TimeUnit.SECONDS) .addNetworkInterceptor(loggingInterceptor) .build(); retrofit = new Retrofit.Builder() .baseUrl(Constant.BASE_IP) .client(client) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); } public static RetrofitManage getInstance(){ if(retrofitManage == null){ synchronized (RetrofitManage.class){ if(retrofitManage == null){ retrofitManage = new RetrofitManage(); } } } return retrofitManage; } /** * 獲取retrofit物件 * @return */ public Retrofit getRetrofit() { return retrofit; } }
其中轉換器使用的是Gson的GsonConverterFactory
其他選擇還有
然後獲取api:Jackson: com.squareup.retrofit2:converter-jackson Moshi: com.squareup.retrofit2:converter-moshi Protobuf: com.squareup.retrofit2:converter-protobuf Wire: com.squareup.retrofit2:converter-wire Simple XML: com.squareup.retrofit2:converter-simplexml Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
public static BoxOfficeApi boxOfficeApi;
public static BoxOfficeApi getBoxOfficeApi(){
if(boxOfficeApi == null){
boxOfficeApi = RetrofitManage.getInstance().getRetrofit().create(BoxOfficeApi.class);
}
return boxOfficeApi;
}
在activity中(rxjava):
BoxOfficeConnection.getBoxOfficeApi()
.getBoxOfficeData(Constant.JUHE_KEY, "CN") //請求引數
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ServiceResult<List<BoxOffice>>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable throwable) {
if (throwable instanceof HttpException) {
HttpException error = (HttpException) throwable;
} else if(throwable instanceof JsonSyntaxException){
Log.w("log", "Json轉換錯誤");
}
throwable.printStackTrace();
}
@Override
public void onNext(ServiceResult<List<BoxOffice>> data) {
adapter.mList = data.getResult();
rcv.setAdapter(adapter);
}
});
這邊要注意的是錯誤異常處理,可以有3種情況:
1.Observable<User>,直接使用body。對於響應碼為2XX的,在OnNext方法中直接返回反序列化的body。而非2XX相應碼在onError方法中表現為 HttpException ,網路錯誤在OnError方法中表現為IOException。
2.Observable<Response<User>>,使用 Response 包裹body。所有Http請求的響應體都可以在OnNext方法中拿到,不管響應碼是否為2XX。而網路錯誤會在OnError方法中表現為IOException。
3.Observable<Result<User>>,使用 Result 包裹body。所有Http請求的響應體和網路錯誤都會在OnNext方法中。
我這邊是選擇了第一種,具體的處理要根據情況處理。