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