The simple use of Retrofit to implement network requests using Retrofit+Rxjava was covered in the last article and won’t be covered today. Today, I’m going to share how to encapsulate a RetrofitManager management class with Rxjava for unified management of networked operations.

Let’s take a look at the use of encapsulation first:

              RetrofitManager.getInstance().getRequestService().getWeather("Beijing") .compose(RxSchedulers.io_main()) .subscribeWith(new DisposableObserver<Object>() { @Override public void onNext(Object  result) { Log.e("TAG"."result=" + result.toString());
                                }

                                @Override
                                public void onError(Throwable e) {
                                    Log.e("TAG"."onError=" + e.getMessage());
                                }

                                @Override
                                public void onComplete() {
                                    Log.e("TAG"."onComplete"); }});Copy the code

After encapsulation, you see the usage, chain call, one step in place, very simple and clear. I’m going to walk you through the process of encapsulating a RetrofitManager.

Ii encapsulates Retrofit+Rxjava’s management class RetrofitManager

    //rxandroid
    implementation 'the IO. Reactivex. Rxjava2: rxandroid: 2.0.2'
    //rxjava
    implementation 'the IO. Reactivex. Rxjava2: rxjava: 2.1.10'
    //retrofit
    implementation "Com. Squareup. Retrofit2: retrofit: 2.4.0." "
    //gsonConverter
    implementation "Com. Squareup. Retrofit2: converter - gson: 2.4.0." "
    //rxjavaAdapter
    implementation "Com. Squareup. Retrofit2: adapter - rxjava2:2.4.0." "
    //retrofit logPrint the implementation'com. Squareup. Okhttp3: logging - interceptor: 3.4.1 track'
Copy the code

(Note: Android Studio3.0 dependencies changed from Compile to implementation.) (2) ① Create RetrofitManager class and provide singleton

Public class RetrofitManager {/** * get singleton */ private static RetrofitManager mInstance; public static RetrofitManagergetInstance() {
        if (mInstance == null) {
            synchronized (RetrofitManager.class) {
                if(mInstance == null) { mInstance = new RetrofitManager(); }}}returnmInstance; }}Copy the code

② Configure OkHttp and build Retrofit objects

  private static final long DEFAULT_TIMEOUT = 60L;
  public Retrofit getRetrofit() {
        if (retrofit == null) {
            synchronized (RetrofitManager.class) {
                if(retrofit == null) {OkHttpClient mClient = new okHttpClient.builder () // Add public query parameter //.addInterceptor(new) CommonQueryParamsInterceptor ()) / /. AddInterceptor (new MutiBaseUrlInterceptor ()) / / add the header addInterceptor (new HeaderInterceptor()).addInterceptor(new LoggingInterceptor()) .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(DEFAULT_TIMEOUT, Timeunit.seconds). ReadTimeout (DEFAULT_TIMEOUT, timeunit.seconds) // Add an HTTPS certificate. If there is an srca.cer certificate, SslSocketFactory (getSSLSocketFactory(context,"srca.cer")) .build(); Retrofit = new retrofit.builder ().baseurl (BASE_URL)// the baseUrl is recommended to end with / AddConverterFactory (GsonConverterFactory. The create ()) / / set the Json converter AddCallAdapterFactory (RxJava2CallAdapterFactory. The create ()) / / RxJava adapter. The client (mClient). The build (); }}}returnretrofit; } private static SSLSocketFactory getSSLSocketFactory(Context Context, String name) {if (context == null) {
            throw new NullPointerException("context == null"); } // Use CertificateFactory to generate a certificate. InputStream inputStream = null; Certificate certificate; try { inputStream = context.getResources().getAssets().open(name); } catch (IOException e) { e.printStackTrace(); } try { certificateFactory = CertificateFactory.getInstance("X.509");
            certificate = certificateFactory.generateCertificate(inputStream);

            //Create a KeyStore containing our trusted CAs
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(null, null);
            keyStore.setCertificateEntry(name, certificate);

            //Create a TrustManager that trusts the CAs in our keyStore
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);

            //Create an SSLContext that uses our TrustManager
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
            return sslContext.getSocketFactory();

        } catch (Exception e) {

        }
        return null;
    }
Copy the code

③ Create an instance of the ApiServe interface by proxy.

  public ApiService getRequestService() {
        return getRetrofit().create(ApiService.class);
    }
Copy the code

ApiService is a self-defined interface. All network request interfaces are configured on this interface. The configuration of network request urls can refer to the configuration of Retrofit request parameters

Interface ApiService {// Get the weather information in Beijing //"https://www.sojson.com/open/api/weather/json.shtml?city=" + "Beijing"
    @GET("weather/json.shtml")
    Observable<Object> getWeather(@Query("city")String city); // Upload file @post ("upload/")
    Observable<UserAvatarBean> uploadFile(@Body RequestBody body);
}
Copy the code

(4) the Header configuration

*/ public class HeaderInterceptor implements Interceptor {@override public Response Intercept (Chain) chain) throws IOException { Request request = chain.request(); Request requestBuilder = request.newBuilder() .addHeader("Connection", HEADER_CONNECTION)
                    .addHeader("token"."token-value")
                    .method(request.method(), request.body())
                    .build();
            returnchain.proceed(requestBuilder); }}Copy the code

⑤Retrofit log printing

/ * * *logPrint: Reference: http://blog.csdn.net/csdn_lqr/article/details/61420753 */ public class LoggingInterceptor implements Interceptor { @override public Response Intercept (Chain Chain) throws IOException {// The Chain contains request and Response, So you can take anything from here Request Request = chain.request(); long t1 = System.nanoTime(); String method = request.method(); JSONObject jsonObject = new JSONObject();if ("POST".equals(method) || "PUT".equals(method)) {
                if (request.body() instanceof FormBody) {
                    FormBody body = (FormBody) request.body();
                    if(body ! = null) {for (int i = 0; i < body.size(); i++) {
                            try {
                                jsonObject.put(body.name(i), body.encodedValue(i));
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    Log.e("request", String.format("Request %s on %s% nRequestParams:%s%nMethod:%s",
                            request.url(), chain.connection(), jsonObject.toString(), request.method()));
                } else {
                    Buffer buffer = new Buffer();
                    RequestBody requestBody = request.body();
                    if(requestBody ! = null) { request.body().writeTo(buffer); String body = buffer.readUtf8(); Log.e("request", String.format("Request %s on %s% nRequestParams:%s%nMethod:%s", request.url(), chain.connection(), body, request.method())); }}}else {
                Log.e("request", String.format("Request %s on %s%nMethod:%s", request.url(), chain.connection(), request.method())); } Response response = chain.proceed(request); long t2 = System.nanoTime(); ResponseBody ResponseBody = response.peekBody(1024 * 1024); Log.e("request",
                    String.format("Retrofit receive response: %s %n Return JSON: [%s] %n Time: %.1fms",
                            response.request().url(),
                            responseBody.string(),
                            (t2 - t1) / 1e6d
                    ));
            returnresponse; }}Copy the code

Look at the effect of log printing. With log printing, we can easily debug each network request.

OkHttp Interceptor

Let’s take a quick look at what an interceptor is. It’s official: Interceptors are a powerful mechanism for monitoring, overriding, and retrying calls. Intercepts logs of outgoing requests and incoming responses. For example: Biaoju escorted a box of silver coins through a mountain path, suddenly from the mountain down a mountain thieves stopped biaoju road, biaoju body valuable things after the clean will be released. The robber is the interceptor, and the biaoju is a network request that is performing a task, and the parameters in the request are the ingot carried by biaoju. The interceptor can validate the parameters carried by the network request and then release it. This actually designed the idea of AOP programming (faceted programming).

The Interceptors take you through Retrofit 2.0 source code

Attach the complete code for RetrofitManager (including Retrofit file upload) :

package com.zongxueguan.naochanle_android.net.retrofit;

import com.zongxueguan.naochanle_android.global.API;
import com.zongxueguan.naochanle_android.retrofitrx.ApiService;
import com.zongxueguan.naochanle_android.util.UserConstants;
import com.zxg.framework.library.common.log.Elog; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import java.io.IOException; import java.util.List; import java.util.concurrent.TimeUnit; import okhttp3.CacheControl; import okhttp3.FormBody; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; import okhttp3.logging.HttpLoggingInterceptor; import okio.Buffer; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; /** * Created by JoJo on 2018/4/24. * wechat:18510829974 * description: */ public class RetrofitManager {/** * private static RetrofitManager mInstance; private static final long DEFAULT_TIMEOUT = 60L; private Retrofit retrofit = null; // Request header information Private Final String HEADER_CONNECTION ="keep-alive";

    public static RetrofitManager getInstance() {
        if (mInstance == null) {
            synchronized (RetrofitManager.class) {
                if(mInstance == null) { mInstance = new RetrofitManager(); }}}return mInstance;
    }

    public Retrofit getRetrofit() {
        if (retrofit == null) {
            synchronized (RetrofitManager.class) {
                if(retrofit == null) {OkHttpClient mClient = new okHttpClient.builder () // addInterceptor(new) CommonQueryParamsInterceptor()) // .addInterceptor(new MutiBaseUrlInterceptor()) .addInterceptor(new HeaderInterceptor()).addInterceptor(new LoggingInterceptor()) .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) .build(); Retrofit = new retrofit.builder ().baseurl (api.getinstance ().base_api_url)// baseUrl recommendations end with / AddConverterFactory (GsonConverterFactory. The create ()) / / set the Json converter AddCallAdapterFactory (RxJava2CallAdapterFactory. The create ()) / / RxJava adapter. The client (mClient). The build (); }}}return retrofit;
    }

    public ApiService getRequestService() {
        returngetRetrofit().create(ApiService.class); } / public query parameter Settings * * * * / public class CommonQueryParamsInterceptor implements Interceptor {@ Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl url = request.url().newBuilder() .addQueryParameter("paramsA"."a")
                    .addQueryParameter("paramsB"."b")
                    .build();
            returnchain.proceed(request.newBuilder().url(url).build()); */ public class HeaderInterceptor implements Interceptor {@override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Request requestBuilder = request.newBuilder() .addHeader("Connection", HEADER_CONNECTION)
                    .addHeader("token"."token-value")
                    .method(request.method(), request.body())
                    .build();
            returnchain.proceed(requestBuilder); Public class CacheInterceptor implements Interceptor {@override public Response Intercept (Chain) chain) throws IOException { Request request = chain.request(); request.newBuilder().cacheControl(CacheControl.FORCE_CACHE) .build(); Response response = chain.proceed(request); int maxAge = 0; Response.newbuilder ().header(); response.newBuilder().header();"Cache-Control"."public, max-age=" + maxAge)
                    .removeHeader("Retrofit"Build (); // Clear the header, because the server will return some interference if it does not support it. Int maxStale = 60 * 60 * 24 * 28; response.newBuilder() .header("Cache-Control"."public, only-if-cached, max-stale=" + maxStale)
                    .removeHeader("nyn")
                    .build();
            returnresponse; }} / * * *logPrint: http://blog.csdn.net/csdn_lqr/article/details/61420753 * / public class LoggingInterceptor implements Interceptor { @override public Response Intercept (Chain Chain) throws IOException {// The Chain contains request and Response, So you can take anything from here Request Request = chain.request(); long t1 = System.nanoTime(); String method = request.method(); JSONObject jsonObject = new JSONObject();if ("POST".equals(method) || "PUT".equals(method)) {
                if (request.body() instanceof FormBody) {
                    FormBody body = (FormBody) request.body();
                    if(body ! = null) {for (int i = 0; i < body.size(); i++) {
                            try {
                                jsonObject.put(body.name(i), body.encodedValue(i));
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    Elog.e("request", String.format("Request %s on %s% nRequestParams:%s%nMethod:%s",
                            request.url(), chain.connection(), jsonObject.toString(), request.method()));
                } else {
                    Buffer buffer = new Buffer();
                    RequestBody requestBody = request.body();
                    if(requestBody ! = null) { request.body().writeTo(buffer); String body = buffer.readUtf8(); Elog.e("request", String.format("Request %s on %s% nRequestParams:%s%nMethod:%s", request.url(), chain.connection(), body, request.method())); }}}else {
                Elog.e("request", String.format("Request %s on %s%nMethod:%s", request.url(), chain.connection(), request.method())); } Response response = chain.proceed(request); long t2 = System.nanoTime(); ResponseBody ResponseBody = response.peekBody(1024 * 1024); Elog.e("request",
                    String.format("Retrofit receive response: %s %n Return JSON: [%s] %n Time: %.1fms",
                            response.request().url(),
                            responseBody.string(),
                            (t2 - t1) / 1e6d
                    ));
            returnresponse; }} /** * PrintslogLogging: This interceptor is used to log information about network requests in applications */ private HttploggingtorgetHttpLogingInterceptor() {
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {// Contains all request information // prints only if the response received is JSONif ("{".equals(message) || "[".equals(message)) {
                    Log.d("TAG"."Received response:" + message);
                }
                Log.d("TAG"."message="+ message); }}); httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);return httpLoggingInterceptor;
    }

    private String BASE_URL_OTHER = "http://wthrcdn.etouch.cn/"; /** * Add interceptors that can handle multiple baseurLs: http://blog.csdn.net/qq_36707431/article/details/77680252 * Retrofit (OKHttp) BaseUrl cases url more perfect real-time automatic substitution solution: / / https://www.2cto.com/kf/201708/663977.html Beijing / / @ Headers ({http://wthrcdn.etouch.cn/weather_mini?city="url_name:other"})
//    @GET("weather_mini")
//    Observable<WeatherEntity> getMessage(@Query("city") String city); */ private class MutiBaseUrlInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException {// Obtain request Request request = chain.request(); OldHttpUrl oldHttpUrl = request.url(); // HttpUrl oldHttpUrl = request.url(); Request.builder builder = request.newBuilder(); Url_name List<String> headerValues = request.headers("url_name");
            if(headerValues ! = null && headervalues.size () > 0) {// If there is a header, delete the configured header first, so header is only used between app and okhttp."url_name"); BaseUrl String headerValue = headerValues.get(0); HttpUrl newBaseUrl = null;if ("other".equals(headerValue)) {
                    newBaseUrl = HttpUrl.parse(BASE_URL_OTHER);
//                } else if ("other".equals(headerValue)) {
//                    newBaseUrl = HttpUrl.parse(BASE_URL_PAY);
                } else{ newBaseUrl = oldHttpUrl; } // HttpUrl newFullUrl = oldhttpurl.newBuilder ().scheme()"http"Host (newBaseurl.host ())// Change the host name. Port (newBaseurl.port ())// Change the port .removePathSegment(0)// Remove the first argument v1.build (); // Rebuild the request with Builder.url (newFullUrl).build(); // Then return a response to end modifying elog.e ("Url"."intercept: " + newFullUrl.toString());
                return chain.proceed(builder.url(newFullUrl).build());
            }
            returnchain.proceed(request); }} /** * Retrofit uploads files ** @param mImagePath * @return*/ public RequestBody getUploadFileRequestBody(String mImagePath) { File file = new File(mImagePath); RequestBody = new MultipartBody.builder ().setType(multipartbody.form).addFormDatApart ()"file", file.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file))
                .build();
        returnrequestBody; }}Copy the code