1. 程式人生 > >Retrofit2.0和RxJava2.0的簡單封裝

Retrofit2.0和RxJava2.0的簡單封裝

一、首先新增專案依賴:

    implementation "com.squareup.okhttp3:logging-interceptor:$var.loggingInterceptor"
    implementation "com.squareup.okhttp3:okhttp:$var.okhttp"
    implementation "com.squareup.retrofit2:retrofit:$var.retrofit"
    implementation "com.google.code.gson:gson:$var.gson"
    implementation "com.squareup.retrofit2:converter-gson:$var
.converterGson"
implementation "com.squareup.retrofit2:adapter-rxjava:$var.adapterRxjava" implementation "io.reactivex:rxandroid:$var.rxandroid" implementation "io.reactivex:rxjava:$var.rxjava" implementation "com.squareup.retrofit2:converter-scalars:$var.converterScalars"

二、建立介面呼叫類

public interface APIService {

    /**
     * post方式請求網路引數
     *
     * @param token 請求引數
     * @return
     */
    @FormUrlEncoded
    @POST("AppInfo.php")
    Observable<BaseEntity<AppInfo>> getAppInfo(@Field("token") String token);

    @FormUrlEncoded
    @POST("FunctionList.php")
    Observable<BaseEntity<List<FunctionItem>>> getFunctionList(@Field
("token") String token); }

三、封裝retrofit

public class HttpMethods {

    private static final String BASE_URL = "http://xxxxxxxxxxxxxx";
    private static final long DEFAULT_TIME = 10000L;
    private Retrofit retrofit;
    private final String TAG = HttpMethods.class.getSimpleName();

    private static class SingletonHolder {
        private static final HttpMethods INSTANCE = new HttpMethods();
    }

    private HttpMethods() {
        //攔截並列印日誌資訊
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                LogUtils.setTag(TAG);
                LogUtils.json(message);
            }
        }).setLevel(HttpLoggingInterceptor.Level.BODY);
        //初始化OKHttp
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(DEFAULT_TIME, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIME, TimeUnit.SECONDS)
                .writeTimeout(DEFAULT_TIME, TimeUnit.SECONDS)
                .addInterceptor(httpLoggingInterceptor)
                .retryOnConnectionFailure(true)
                .build();
        //初始化Retrofit
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(okHttpClient)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }

    public static HttpMethods getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public <T> T createService(Class<T> clazz) {
        return retrofit.create(clazz);
    }
}

四、返回資料統一封裝

public class BaseEntity<T> implements Serializable{
    private int code;
    private String message;
    private T data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

五、統一執行緒排程

public class DefaultTransformer<T> implements Observable.Transformer<T, T> {


    @Override
    public Observable<T> call(Observable<T> tObservable) {
        return tObservable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Func1<T, T>() {
                    @Override
                    public T call(T t) {
                        BaseEntity<T> baseEntity = (BaseEntity<T>) t;
                        if (baseEntity.getCode() != 200) {
                            throw new APIException(baseEntity.getCode(), baseEntity.getMessage());
                        }
                        return t;
                    }
                });
    }
    public static <T> DefaultTransformer<T> create(){
        return new DefaultTransformer<>();
    }
}

六、返回錯誤統一處理

public abstract class APISubscriber<T> extends Subscriber<T> {

    private final String TAG = APISubscriber.class.getSimpleName();
    private QMUITipDialog tipDialog;

    protected APISubscriber() {

    }

    protected APISubscriber(Context context) {
        QMUITipDialog.Builder builder = new QMUITipDialog.Builder(context);
        builder.setTipWord("載入中");
        builder.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING);
        tipDialog = builder.create();
        tipDialog.setCancelable(true);
    }

    @Override
    public void onStart() {
        super.onStart();
        if (tipDialog != null) {
            tipDialog.show();
        }
    }

    @Override
    public void onCompleted() {
        if (tipDialog != null && tipDialog.isShowing()) {
            tipDialog.dismiss();
        }
    }


    @Override
    public void onError(Throwable e) {
        if (tipDialog != null && tipDialog.isShowing())
            tipDialog.dismiss();
        if (e instanceof APIException) {
            LogUtils.e("處理伺服器返回的錯誤");
        } else if (e instanceof ConnectException) {
            LogUtils.e("網路異常,請檢查網路");
        } else if (e instanceof TimeoutException || e instanceof SocketException) {
            LogUtils.e("網路異常,請檢查網路");
        } else if (e instanceof JsonSyntaxException) {
            LogUtils.e("資料解析異常");
        } else {
            LogUtils.e("服務端異常");
        }
        e.printStackTrace();
    }
}

七、使用

    /**
     * 獲取APP版本資訊
     *
     * @param aty
     */
    public void getAppInfo(final FunctionListAty aty) {

        final Subscription subscription = HttpMethods.getInstance()
                .createService(APIService.class)
                .getAppInfo("123")
                .compose(DefaultTransformer.<BaseEntity<AppInfo>>create())
                .subscribe(new APISubscriber<BaseEntity<AppInfo>>(aty) {
                    @Override
                    public void onNext(BaseEntity<AppInfo> appInfoBaseEntity) {
                        AppInfo appInfo = appInfoBaseEntity.getData();
                        if (appInfo != null) {
                            Constants.DEFAULT_URL = appInfo.getApp_download_url();
                            new UpdateManager(aty, appInfo).checkUpdate();
                        }
                    }
                });
        aty.addSubscription(subscription);
    }

八、連續請求多個介面

 /**
     * 多個請求合併
     */
    public void getRequest(final FunctionListAty aty) {
        final APIService apiService = HttpMethods.getInstance().createService(APIService.class);
        Observable<BaseEntity<AppInfo>> appInfo = apiService.getAppInfo("123");
        Observable<BaseEntity<List<FunctionItem>>> functionList = apiService.getFunctionList("123");
        final Subscription subscription = Observable.mergeDelayError(appInfo, functionList)
                .compose(DefaultTransformer.create())
                .subscribe(new APISubscriber<Object>(aty) {

                    @Override
                    public void onNext(Object o) {
                        if (o instanceof BaseEntity) {
                            BaseEntity baseEntity = (BaseEntity) o;
                            Object data = baseEntity.getData();
                            if (data != null) {
                                if (data instanceof AppInfo) {
                                    LogUtils.i("請求成功---版本資訊");
                                    AppInfo appInfo = (AppInfo) data;
                                    Constants.DEFAULT_URL = appInfo.getApp_download_url();
                                    new UpdateManager(aty, appInfo).checkUpdate();
                                } else if (data instanceof List) {
                                    LogUtils.i("請求成功---列表");
                                    List<FunctionItem> functionItemList = (List<FunctionItem>) data;
                                    functionItems.addAll(functionItemList);
                                }
                            }
                        }
                    }
                });
        aty.addSubscription(subscription);
    }