Andriod RX+Retrofit Basic Learning and Simple Encapsulation

Posted by markjia on Sat, 18 May 2019 14:09:08 +0200

Recently, new work has been added. Android products use RX+retrofit as the framework of network interaction, which has never been used before, and only make up for it by themselves. Here I share with you the results of my study, which is also convenient for me to review in the future. There are many similar articles, and the encapsulation is quite similar. In particular, a record is written in the hope that you can really understand what you have seen and turn it into your own.

 private void requestLogin(String name,String pwd){
        APILoader personAPILoader=new APILoader();
        personAPILoader.login(name,pwd)
                .doOnNext(new Consumer<LoginBean>() {
                    @Override
                    public void accept(LoginBean loginBean) throws Exception {

                    }
                })
                .subscribe(new NetDisposable<>());
    }

Above is the complete code for the author to initiate the landing request, or more concise. We process our result logic in doOnNext(), which executes before onNext().
Next, we will analyze the whole process step by step from outside to inside.

APILoader and ObjectLoader

public class APILoader extends ObjectLoader {
    private PersonAPI mPersonAPI;
    public APILoader(){
        mPersonAPI=RetrofitServiceManager.getInstance().create(PersonAPI.class);
    }
    public Observable<LoginBean> login(String name,String pwd){
        return observe(mPersonAPI.loginRX(name,pwd));
    }
}

public class ObjectLoader {
    protected  <T> Observable<T> observe(Observable<T> observable){
        return observable
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());

    }
}

Object Loader is our own Loader parent class. It is used for inheritance of all Loader classes. It encapsulates the observation method. The parameters and return values are Observable. The function is to unify Observable processing and handle some repetitive operations, such as thread processing between the observer and the observee.
APILoader inherits from ObjectLoader and manages the Service API interface of retrofit to avoid creating once every time it is used. All Loaders inherit ObjectLoader and configure observable uniformly.
Here we see two new things, the singleton RetrofitService Manager and the interface PersonAPI.

Interface PersonAPI

public interface PersonAPI {
    @GET("td_web/td/login/")
    Call<LoginBean> login(@Query("name") String name,@Query("pwd") String pwd);
    @GET("td_web/td/login/")
    Observable<LoginBean> loginRX(@Query("name") String name, @Query("pwd") String pwd);
}

The Person API here is what we call the Service API of retrofit. In my opinion, it is the essence of retrofit. It uses interface injection to create and manage our request interface.

RetrofitServiceManager

public class RetrofitServiceManager {
    private static final int DEFAULT_TIME_OUT = 5;//Timeout time 5s
    private static final int DEFAULT_READ_TIME_OUT = 10;//Read write timeout
    private static final String BASE_URL="http://222.211.90.120:6071/;//root address
    private static  RetrofitServiceManager retrofitServiceManager;
    //Log Display Level
    private Retrofit mRetrofit;
    /**
     * Get Retrofit Service Manager
     * @return
     */
    public synchronized static RetrofitServiceManager getInstance(){
        if(retrofitServiceManager==null) return new RetrofitServiceManager();
        return retrofitServiceManager;
    }
    private RetrofitServiceManager(){
        // Create OKHttpClient
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS);//Connection timeout
        builder.writeTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//Write operation timeout
        builder.readTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//Read operation timeout
        builder.retryOnConnectionFailure(true);

        // Add Common Parameter Interceptor
        BasicParamsInterceptor basicParamsInterceptor = new BasicParamsInterceptor.Builder()
                .addHeaderParam("paltform","android")
                .addHeaderParam("userToken","1234343434dfdfd3434")
                .addHeaderParam("userId","123445")
                .build();
        //Add Log Print Interceptor
        HttpLoggingInterceptor loggingInterceptor=new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);//Setting Log Display Level
        builder.addInterceptor(basicParamsInterceptor);
        builder.addInterceptor(loggingInterceptor);
        // Create Retrofit
        mRetrofit = new Retrofit.Builder()
                .client(builder.build())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(BASE_URL)
                .build();
    }



    /**
     * Get the corresponding Service
     * @param service Service class
     * @param <T>
     * @return
     */
    public <T> T create(Class<T> service){
        return mRetrofit.create(service);
    }
}

RetrofitService Manager manages the creation of Service API, publishes the create method, and returns an instance of Service Api.
At the same time, OkHttpClient is encapsulated and introduced, which can add and restrict the common parameters and request time of the request.
We can see that this single class, in the construction method, we can uniformly configure OkHttpClient and add interceptors and so on. At the same time, to build Retrofit attributes in a unified way, we only need to provide create methods and build different service API instances.
It is worth mentioning here that HttpLogging Interceptor. He is a retrofit log interceptor for printing request addresses and other information, and can set the level of printing information through setLevel (the higher the level, the more detailed the content). Retrofit makes network requests and wants to print request information. For the time being, it only finds this method, unlike OkHttp3, which can get url directly.

NetObserver Network Request Observer

A simple encapsulated unified observer of network requests manages and prints common errors in network requests.

public class NetObserver<T> extends DisposableObserver<T> {
    private String message="";
    private final String TAG="NetObserver";
    @Override
    public void onNext(T t) {

    }

    @Override
    public void onError(Throwable e) {
        if (e instanceof HttpException) {
            message = "network error";
        } else if (e instanceof SocketTimeoutException) {
            message = "Network connection timeout";
        } else if (e instanceof ConnectException) {
            message = "connection failed";
        } else if (e instanceof IOException) {
            message = "network error";
        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
            message = "Certificate validation failed";
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {
            //All considered parsing errors
            message="Error in data parsing";
        } else {
            message = "unknown error";
        }
        Log.e(TAG,message);
    }

    @Override
    public void onComplete() {

    }
}

Reference article:

Basic, encapsulation and project use of RxJava 2+Retrofit 2+OkHttp3

This article source code:

Retrofit+RX Learning Github Source Address

Topics: Retrofit network Android SSL