RxJava2 and Retrofit2 encapsulation (neat, simple, practical)

Keywords: Android Java Retrofit network

RxJava2 and Retrofit2 are old partners. Previously, I wrote a "unified processing of single request by RxJava and Retrofit2", which is Rxjava1.0. This time, Rxjava2.0 and Retrofit2 are used for encapsulation, which is clean, simple and practical. Compared with Rxjava1, RxJava2 optimizes and changes many things. There are many articles written by great gods on the Internet, so there is no need to paste and copy them here. Please leave a message below if you have any questions during the process of encapsulation. The author will reply one by one.
Core network request:

package com.lin.netrequestdemo.data;


import android.util.Log;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class RxNet {
    /**
     * Unified processing of individual requests
     *
     * @param observable
     * @param callBack
     * @param <T>
     */
    public static <T> Disposable request(Observable<BaseResponse<T>> observable, final RxNetCallBack<T> callBack) {
        return observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .onErrorReturn(new Function<Throwable, BaseResponse<T>>() {
                    @Override
                    public BaseResponse<T> apply(Throwable throwable) {
                        Log.e("LinNetError", throwable.getMessage());
                        callBack.onFailure(ExceptionHandle.handleException(throwable));
                        return null;
                    }
                })
                .subscribe(new Consumer<BaseResponse<T>>() {
                    @Override
                    public void accept(BaseResponse<T> tBaseResponse) {
                        if (tBaseResponse.getCode().equals("200")) {
                            callBack.onSuccess(tBaseResponse.getData());

                        } else {
                            callBack.onFailure(tBaseResponse.getMsg());
                        }
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) {
                        Log.e("LinNetError", "Single request error" + throwable.getMessage());
                    }
                });
    }

    /**
     * Unified processing of individual requests
     * No body returned
     */
    public static Disposable requestWithoutBody(Observable<BaseResponse> observable,
                                                final RxNetCallBack<String> callBack) {
        return observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .onErrorReturn(new Function<Throwable, BaseResponse>() {
                    @Override
                    public BaseResponse apply(Throwable throwable) {
                        Log.v("LinNetError", throwable.getMessage());
                        callBack.onFailure(ExceptionHandle.handleException(throwable));
                        return null;
                    }
                })
                .subscribe(new Consumer<BaseResponse>() {
                    @Override
                    public void accept(BaseResponse baseResponse) {
                        if (baseResponse.getCode().equals("200")) {
                            callBack.onSuccess(baseResponse.getMsg());
                        } else {
                            callBack.onFailure(baseResponse.getMsg());
                        }
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) {
                        Log.v("LinNetError", "Single request error:No, body" + throwable.getMessage());
                    }
                });

    }
}

A callback is a generic callback

package com.lin.netrequestdemo.data;


public interface RxNetCallBack<T> {
    /**
     * Data request successful
     *
     * @param data Data requested to
     */
    void onSuccess(T data);

    /**
     * Data request failed
     */
    void onFailure(String msg);
}

Error exception handling (possibly incomplete):

package com.lin.netrequestdemo.data;

import android.net.ParseException;

import com.google.gson.JsonParseException;


import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;

import java.net.ConnectException;

import retrofit2.HttpException;


public class ExceptionHandle {

    private static final int UNAUTHORIZED = 401;
    private static final int FORBIDDEN = 403;
    private static final int NOT_FOUND = 404;
    private static final int REQUEST_TIMEOUT = 408;
    private static final int INTERNAL_SERVER_ERROR = 500;
    private static final int BAD_GATEWAY = 502;
    private static final int SERVICE_UNAVAILABLE = 503;
    private static final int GATEWAY_TIMEOUT = 504;

    public static String handleException(Throwable e) {
        String errorMsg;
        if (e instanceof HttpException) {
            HttpException httpException = (HttpException) e;
            switch (httpException.code()) {
                case UNAUTHORIZED:
                case FORBIDDEN:
                case NOT_FOUND:
                case REQUEST_TIMEOUT:
                case GATEWAY_TIMEOUT:
                case INTERNAL_SERVER_ERROR:
                case BAD_GATEWAY:
                case SERVICE_UNAVAILABLE:
                default:
                    errorMsg = "network error";
                    break;
            }
            return errorMsg + ":" + httpException.code();
        } else if (e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException) {
            return "Parsing error";
        } else if (e instanceof ConnectException) {
            return "connection failed";
        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
            return "Certificate validation failed";
        } else if (e instanceof ConnectTimeoutException) {
            return "connection timed out";
        } else if (e instanceof java.net.SocketTimeoutException) {
            return "connection timed out";
        } else {
            return "unknown error";
        }
    }

}

Then there's ApiManager:

package com.lin.netrequestdemo.data.api;

import android.util.Log;

import com.lin.netrequestdemo.data.AppConstants;

import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;


public class ApiManager {

    private Retrofit client;

    private ApiManager() {
        client = new Retrofit.Builder()
                .baseUrl(AppConstants.Base_Url_Test)
                .client(initClient())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    private static volatile MallApi INSTANCE;

    public static MallApi getInstance() {
        if (INSTANCE == null) {
            synchronized (ApiManager.class) {
                if (INSTANCE == null) {
                    INSTANCE = new ApiManager().getMallApi();
                }
            }
        }
        return INSTANCE;
    }

    private MallApi getMallApi() {
        return client.create(MallApi.class);
    }

    private static OkHttpClient initClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        //Declaration log class
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.v("LinNet", message);
            }
        });
        //Set log level
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        //delayed
        builder.addInterceptor(httpLoggingInterceptor)
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS);
        return builder.build();
    }

}

How to use it?

showLoading();
        Map<String, String> map = new ArrayMap<>();
        map.put("action", "pricetrend");
        addCompositeDisposable(RxNet.request(ApiManager.getInstance().getCat(map), new RxNetCallBack<List<CatBean>>() {
            @Override
            public void onSuccess(List<CatBean> data) {
                hideLoading();
                showToast("Get list succeeded" + data.get(0).toString());
            }

            @Override
            public void onFailure(String msg) {
                hideLoading();
                showToast(msg);
            }
        }));

Demo offers https://github.com/FriendLin/NetRequestDemo

Posted by phpmixx on Wed, 11 Dec 2019 07:20:10 -0800