美文网首页网络
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