美文网首页
Retrofit & RxJava 封装篇

Retrofit & RxJava 封装篇

作者: kjy_112233 | 来源:发表于2018-09-13 10:26 被阅读0次

    一、封装RxJava

    (1)BaseResponse封装请求返回数据

    public class BaseResponse<T> {
        private int res_code;
        private String err_msg;
        private T demo;
        //code...
    }
    
    

    (2)BaseObserver封装返回数据处理

    public abstract class BaseObserver<T> implements Observer<BaseResponse<T>> {
        private static final String TAG = "BaseObserver";
    
        @Override
        public void onSubscribe(@NonNull Disposable d) {
        }
    
        @Override
        public void onNext(@NonNull BaseResponse<T> tBaseResponse) {
            if (tBaseResponse.getRes_code() == 200) {
                onSuccess(tBaseResponse.getDemo());
            } else {
                onFailure(null, tBaseResponse.getErr_msg());
            }
        }
    
        @Override
        public void onError(@NonNull Throwable e) {
            try {
                if (e instanceof SocketTimeoutException) {//请求超时
                    onFault(e, "请求超时,请稍后再试");
                } else if (e instanceof ConnectException) {//网络连接超时
                    onFault(e, "网络连接超时,请检查网络状态");
                } else if (e instanceof SSLHandshakeException) {//安全证书异常
                    onFault(e, "安全证书异常");
                } else if (e instanceof HttpException) {//请求的地址不存在
                    int code = ((HttpException) e).code();
                    if (code == 504) {
                        onFault(e, "网络异常,请检查您的网络状态");
                    } else if (code == 404) {
                        onFault(e, "请求的地址不存在");
                    } else {
                        onFault(e, "请求失败");
                    }
                } else if (e instanceof UnknownHostException) {//域名解析失败
                    onFault(e, "域名解析失败");
                } else {
                    onFault(e, "error:" + e.getMessage());
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    
        @Override
        public void onComplete() {
        }
    
        public abstract void onSuccess(T demo);
    
        public abstract void onFailure(Throwable e, String errorMsg);
    
        public abstract void onFault(Throwable e, String errorMsg);
    }
    

    (3)DialogObserver封装网络请求加载提示

    public abstract class DialogObserver<T> extends BaseObserver<T> {
        private boolean mShowDialog;
        private ProgressDialog dialog;
        private Context mContext;
        private Disposable d;
    
    
        private DialogObserver(Context context, Boolean showDialog) {
            mContext = context;
            mShowDialog = showDialog;
        }
    
        public DialogObserver(Context context) {
            this(context, true);
        }
    
        @Override
        public void onSubscribe(@NonNull Disposable d) {
            this.d = d;
            if (!isConnected(mContext)) {
                Toast.makeText(mContext, "未连接网络", Toast.LENGTH_SHORT).show();
                if (d.isDisposed()) {
                    d.dispose();
                }
            } else {
                if (dialog == null && mShowDialog) {
                    dialog = new ProgressDialog(mContext);
                    dialog.setMessage("正在加载中");
                    dialog.show();
                }
            }
        }
    
        @Override
        public void onError(@NonNull Throwable e) {
            if (d.isDisposed()) {
                d.dispose();
            }
            hidDialog();
            super.onError(e);
        }
    
        @Override
        public void onComplete() {
            if (d.isDisposed()) {
                d.dispose();
            }
            hidDialog();
            super.onComplete();
        }
    
        private void hidDialog() {
            if (dialog != null && mShowDialog)
                dialog.dismiss();
            dialog = null;
        }
    
        /**
         * 是否有网络连接,不管是wifi还是数据流量
         */
        private static boolean isConnected(Context context) {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            assert cm != null;
            NetworkInfo info = cm.getActiveNetworkInfo();
            if (info == null) {
                return false;
            }
            return info.isAvailable();
        }
    }
    

    二、封装Retrofit

    (1)NetworkInterface封装网络请求接口

    public interface NetworkInterface {
        String HOST = "http://服务器地址.com/";
    
        @GET()
        Observable<BaseResponse<String>> getBody(@Url String url);
    
        @POST()
        Observable<BaseResponse<RegisterLogin>> registerLogin(@Url String url, @Body RequestBody body);
    }
    

    (2)RetrofitUtils封装拦截器

    public class RetrofitUtils {
        private static final int DEFAULT_TIMEOUT = 10;//超时时间
        private static volatile NetworkInterface networkInterface = null;
    
        /**
         * 创建网络请求接口实例
         */
        public static NetworkInterface getRequestInterface() {
            if (networkInterface == null) {
                synchronized (NetworkInterface.class) {
                    networkInterface = provideRetrofit().create(NetworkInterface.class);
                }
            }
            return networkInterface;
        }
    
        /**
         * 初始化必要对象和参数
         */
        private static Retrofit provideRetrofit() {
            File cacheFile = new File(CPApplication.getContext().getCacheDir(), "cache");
            Cache cache = new Cache(cacheFile, 1024 * 1024 * 100); //100Mb
            OkHttpClient client = new OkHttpClient.Builder()
                    .cache(cache) //设置缓存
                    .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                    .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                    .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                    .addNetworkInterceptor(getRequestHeader())
                    .addInterceptor(getHttpLoggingInterceptor())
                    .addInterceptor(commonParamsInterceptor())
                    .addInterceptor(getResponseHeader())
                    .addInterceptor(getCacheInterceptor())
                    .build();
            //设置网络请求的Url地址
            //设置数据解析器
            //支持RxJava平台
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(NetworkInterface.HOST)//设置网络请求的Url地址
                    .addConverterFactory(GsonConverterFactory.create())//设置数据解析器
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持RxJava平台
                    .client(client)
                    .build();
            return retrofit;
        }
    
        /**
         * 日志拦截器
         */
        private static HttpLoggingInterceptor getHttpLoggingInterceptor() {
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
                    new HttpLoggingInterceptor.Logger() {
                        @Override
                        public void log(String message) {
                            LogUtils.Le("OkHttp", "log = " + message);
                        }
                    });
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            return loggingInterceptor;
        }
    
    
        /**
         * 请求头拦截器
         */
        private static Interceptor getRequestHeader() {
            Interceptor headerInterceptor = new Interceptor() {
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request originalRequest = chain.request();
                    Request.Builder builder = originalRequest.newBuilder();
                    //使用addHeader()不会覆盖之前设置的header,若使用header()则会覆盖之前的header
                    builder.addHeader("Accept", "application/json");
                    builder.addHeader("Content-Type", "application/json; charset=utf-8");
                    builder.addHeader("token", "d08986536b5e3678119aac9b892439a8");
                    builder.removeHeader("User-Agent");
                    builder.method(originalRequest.method(), originalRequest.body());
                    Request.Builder requestBuilder = builder.method(originalRequest.method(), originalRequest.body());
                    Request request = requestBuilder.build();
                    return chain.proceed(request);
                }
            };
            return headerInterceptor;
        }
    
        /**
         * 统一的请求参数拦截器
         */
        private static Interceptor commonParamsInterceptor() {
            Interceptor commonParams = new Interceptor() {
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request originRequest = chain.request();
                    Request request;
                    HttpUrl httpUrl = originRequest.url().newBuilder().
                            addQueryParameter("paltform", "android").
                            addQueryParameter("version", "1.0.0").build();
                    request = originRequest.newBuilder().url(httpUrl).build();
                    return chain.proceed(request);
                }
            };
            return commonParams;
        }
    
        /**
         * 通过响应拦截器实现了从响应中获取服务器返回的time
         */
        private static Interceptor getResponseHeader() {
            Interceptor interceptor = new Interceptor() {
                @NonNull
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    okhttp3.Response response = chain.proceed(chain.request());
                    String timestamp = response.header("time");
                    if (timestamp != null) {
                        //获取到响应header中的time
                    }
                    return response;
                }
            };
            return interceptor;
        }
    
        /**
         * 在无网络的情况下读取缓存,有网络的情况下根据缓存的过期时间重新请求
         */
        private static Interceptor getCacheInterceptor() {
            Interceptor commonParams = new Interceptor() {
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    if (!NetworkUtils.isConnected()) {
                        //无网络下强制使用缓存,无论缓存是否过期,此时该请求实际上不会被发送出去。
                        request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE)
                                .build();
                    }
                    okhttp3.Response response = chain.proceed(request);
                    if (NetworkUtils.isConnected()) {//有网络情况下,根据请求接口的设置,配置缓存。
                        //这样在下次请求时,根据缓存决定是否真正发出请求。
                        String cacheControl = request.cacheControl().toString();
                        //当然如果你想在有网络的情况下都直接走网络,那么只需要
                        //将其超时时间这是为0即可:String cacheControl="Cache-Control:public,max-age=0"
                        int maxAge = 60 * 60; // read from cache for 1 minute
                        return response.newBuilder()
    //                            .header("Cache-Control", cacheControl)
                                .header("Cache-Control", "public, max-age=" + maxAge)
                                .removeHeader("Pragma")
                                .build();
                    } else {
                        //无网络
                        int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
                        return response.newBuilder()
                                .header("Cache-Control", "public,only-if-cached,max-stale=" + maxStale)
                                .removeHeader("Pragma")
                                .build();
                    }
    
                }
            };
            return commonParams;
        }
    }
    

    三、实际用例

    (1)封装网络请求参数

    public class HttpService {
    
        public static Observable<BaseResponse<RegisterLogin>> registerLogin(String phone, String code) {
            Gson gson = new Gson();
            Map<String, String> map = new HashMap<String, String>();
            map.put("phone", phone);
            map.put("code", code);
            String strJson = gson.toJson(map);
            RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), strJson);
            return RetrofitUtils.getRequestInterface()
                    .registerLogin("", body)
                    .observeOn(AndroidSchedulers.mainThread())//回调在主线程
                    .subscribeOn(Schedulers.io());
        }
    }
    

    (2)调用网络请求

    HttpService.registerLogin("", "")
                    .subscribe(new BaseObserver<RegisterLogin>() {
    
                        @Override
                        public void onSuccess(RegisterLogin demo) {
    
                        }
    
                        @Override
                        public void onFailure(Throwable e, String errorMsg) {
    
                        }
    
                        @Override
                        public void onFault(Throwable e, String errorMsg) {
    
                        }
                    });//执行在io线程
    

    相关文章

      网友评论

          本文标题:Retrofit & RxJava 封装篇

          本文链接:https://www.haomeiwen.com/subject/kyebgftx.html