美文网首页网络
Android网络框架二次封装

Android网络框架二次封装

作者: 杨旭_ | 来源:发表于2019-10-12 00:03 被阅读0次

    我来了我来了,今天手把手教你二次封装网络框架

    首先为什么需要二次封装网络框架?

    情景一

    领导说,小明咱们需要有个网络框架,你去调研一下,然后接入到咱们项目,小明赶紧去找,发现目前okhttp最好,而且有好多封装好的比如okgo,然后就把怎么用的记录下来了

     OkGo.<String>post(HttpUrls.APPHOMEAPI)
                    .tag(this)
                    .cacheMode(CacheMode.FIRST_CACHE_THEN_REQUEST)
                    .converter(new StringConvert())
                    .adapt(new ObservableResponse<String>())
                    .subscribeOn(Schedulers.io())
                    .doOnSubscribe(new Consumer<Disposable>() {
                        @Override
                        public void accept(@NonNull Disposable disposable) throws Exception {
                            showLoadingDialog();
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<Response<String>>() {
                        @Override
                        public void onSubscribe(@NonNull Disposable d) {
                            addDisposable(d);
                        }
    
                        @Override
                        public void onNext(@NonNull Response<String> response) {
                            dealNetData(response.body());
                        }
    
    
                        @Override
                        public void onError(@NonNull Throwable e) {
                            e.printStackTrace();
                            ToastUtils.showShort(RMHttpConstant.ERROR_MSG);
                            dismissLoadingDialog();
                        }
    
                        @Override
                        public void onComplete() {
                            dismissLoadingDialog();
                        }
                    });
    
    

    正好 A同事过来了,说这个怎么添加请求头啊,小明记下了说一会告诉你,B同事过来了,说我不会用rxJava怎么办呢,小名记下了说一会告诉你,.....一共来了一万个同事。小明卒。

    原因一:简单好用,傻瓜式的操作。
    情景二

    一万个页面代码刚刚写完,领导说retrofit不错,小明你调研一下,然后替换一下,小明卒。

    原因二:维护性(更换网络框架的成本低,最好一行代码实现替换网络框架)

    开始实践。

    第一步 功能放在接口中,最核心的东西全在这个接口可以一目了然,按照这个约束进行编程。
    public interface XHttp {
    
        /**
         *  post网络请求
         * @param url
         * @param tag
         * @param params
         * @return
         */
    
        void doPost(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack);
    
        void doGet(String url, Object tag, HashMap<String, String> params,IHttpCallBack iokGoCallBack);
    
        void cancel(Object tag);
    }
    
    第二步 实现接口功能

    1,实现接口功能。

    public class OKGoHttpImp implements XHttp {
    
        private HashMap<Object,CompositeDisposable> mDisposables=new HashMap<>();
    
        @Override
        public  void doPost(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack) {
            PostRequest<String> request = OkGo.<String>post(url).tag(tag).headers(OkGoUtil.getHeaders()).params(params, true).converter(new StringConvert());
            request.adapt(new ObservableBody<String>()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    add(tag,d);
                }
    
                @Override
                public void onNext(String s) {
                    iokGoCallBack.onSuccess(s);
                }
    
                @Override
                public void onError(Throwable e) {
                    iokGoCallBack.onFail(e);
                }
    
                @Override
                public void onComplete() {
                }
    
            });
    
        }
    
        @Override
        public void doGet(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack) {
            GetRequest<String> request = OkGo.<String>get(url).tag(tag).headers(OkGoUtil.getHeaders()).params(params, true).converter(new StringConvert());
            request.adapt(new ObservableBody<String>()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    add(tag,d);
                }
    
                @Override
                public void onNext(String s) {
                    iokGoCallBack.onSuccess(s);
                }
    
                @Override
                public void onError(Throwable e) {
                    iokGoCallBack.onFail(e);
                }
    
                @Override
                public void onComplete() {
    
                }
            });
    
        }
    
        private void add(Object tag, Disposable d){
            CompositeDisposable disposables = mDisposables.get(tag);
            if (disposables==null){
                disposables=new CompositeDisposable();
                mDisposables.put(tag,disposables);
            }
            disposables.add(d);
        }
    
        public void cancel(Object tag) {
            OkGo.getInstance().cancelTag(tag);
            CompositeDisposable disposables = mDisposables.get(tag);
            if (disposables!=null){
                disposables.clear();
            }
        }
    
    
    情景三

    领导说okgo不行,咱们试试别的网络框架。
    看上去也没什么问题,而且修改网络框架只需要在这里一次修改就全局替换了。
    小明改完之后,领导说不行,我觉得还是okgo比较好再替换回去吧。
    小明一顿粘贴复制改来改去,如此反复一万次,小明卒。

    接下来代理登场,实现接口,持有的一个接口的实现类,通过初始化传入,看代码
    public final class XHttpClient implements XHttp {
    
        private static XHttp mRealHttp;
    
    
        @Override
        public void doPost(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack) {
             mRealHttp.doPost(url,tag,params,iokGoCallBack);
        }
    
        @Override
        public void doGet(String url, Object tag, HashMap<String, String> params, IHttpCallBack iokGoCallBack) {
             mRealHttp.doGet(url,tag,params,iokGoCallBack);
        }
    
        @Override
        public void cancel(Object tag) {
            mRealHttp.cancel(tag);
        }
    
        private static class Holder {
            private static final XHttpClient INSTANCE = new XHttpClient();
        }
        private XHttpClient() {
        }
    
    
        public static void init(XHttp http) {
            mRealHttp=http;
        }
    
        public static final XHttpClient get() {
            return Holder.INSTANCE;
        }
    
    }
    
    第三步 对外使用
           XHttpClient.init(new OKGoHttpImp());//初始化网络框架
           // XHttpClient.init(new RetrofitImp());//初始化网络框架
          //XHttpClient.init(new OKUtlisImp());//初始化网络框架
         .....
    
           XHttpClient.get().doPost(url, this, params,iHttpCallBack);//外部调用
    

    这里可能有人会说,我多创建几个类实现接口,跟你这个不就一样了吗,也支持多个功能来回切换了?

    替换网络框架还是需要全局都修改,而通过代理则可以实现一行代码替换框架

    优点:框架功能一目了然,直接看接口功能; 一行代码替换底层网络框架。

    最后来张图

    http.png

    数据解析类

    public interface IHttpCallBack {
    
        void onSuccess(String result);
    
        void onFail(Throwable error);
    }
    
    public abstract class XHttpCallBack<result> implements IHttpCallBack {
    
        @Override
        public void onSuccess(String result) {
            int code = XJsonParseUtils.getInt(result, "code");
            if (code==0){
                Type type = TUtils.getTTypeInfo(this, 0);
                result resultBody = XJsonParseUtils.json2Obj(result, type);
                onSuccess(resultBody);
    
            }else {
                String msg = XJsonParseUtils.getString(result, "msg");
                ApiException apiException = new ApiException(code, msg);
                XErrorUtils.processException(apiException);
                onFail(apiException);
            }
            //这里需要处理
        }
    
        @Override
        public void onFail(Throwable error) {
            XErrorUtils.processException(error);
            onError(error);
        }
    
    
        public abstract void onSuccess(result result);
    
        public void onError(Throwable error) {
    
        }
    }
    
    public final class TUtils {
    
        /**
         * @param object 当前 类的实例对象
         * @param index  要获取的泛型的下标
         * @param <T>
         * @return
         */
    
        public static <T> T get(Object object, int index) {
            T t = null;
            try {
                return t = (T) getTClassInfo(object, index).newInstance();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
            return t;
        }
    
        /**
         * 获取泛型的类型
         *
         * @param clazz 泛型类的当前对象
         * @param index  泛型的下标
         * @return
         */
        public static Class<?> getTClassInfo(Class<?> clazz, int index) {
            Type genType = clazz.getGenericSuperclass();
    
            if (!(genType instanceof ParameterizedType)) {
                return Object.class;
            }
            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
    
    
            if (index >= params.length || index < 0) {
                return Object.class;
            }
            if (!(params[index] instanceof Class)) {
                return Object.class;
    
            }
            return (Class) params[index];
        }
    
        public static Class<?> getTClassInfo(Object object, int index) {
            return getTClassInfo(object.getClass(), index);
        }
    
        /**
         * 获取当前类上泛型 的type  可以用来解析
         * @param object
         * @param index
         * @return
         */
        public static Type getTTypeInfo(Object object, int index){
            Type genType = object.getClass().getGenericSuperclass();
    
            if (!(genType instanceof ParameterizedType)) {
                return null;
            }
            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
    
            return  params[index];
        }
    
    }
    

    相关文章

      网友评论

        本文标题:Android网络框架二次封装

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