1. 程式人生 > >Retrofit2初嘗試(rxjava + okhttp3)

Retrofit2初嘗試(rxjava + okhttp3)

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,我們建立一個全域性的管理類方便使用。

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;
    }


}
okhttp3的自帶日誌效果還是不錯的,比較直觀

其中轉換器使用的是Gson的GsonConverterFactory

其他選擇還有

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
然後獲取api:
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方法中。

我這邊是選擇了第一種,具體的處理要根據情況處理。