美文网首页Android学习Android技术知识Android知识
Android链式调用 - 打造第三方的网络引擎

Android链式调用 - 打造第三方的网络引擎

作者: 红橙Darren | 来源:发表于2017-03-01 11:22 被阅读4035次

    1. 概述


    上一期我们提了一下Volley,Okhttp,Retrofit到底应该选哪一个?但是的确目前第三方的网络框架比较多,也不知道再等个几十年会出什么样的,到时候我们可能还是要换,然而随着版本的迭代这是一个很头疼的事情,如果要更换更好的网络框架成本就比较高了,今天我们来看一下怎么样打造一套网络框架引擎,一方面为了封装,一方面为了方便切换网络框架。

    所有分享大纲:2017Android进阶之路与你同行

    视频讲解地址:http://pan.baidu.com/s/1pKWuZrX

    2. 套路分析


    一般在开发中我们往往还要根据需求对第三方的网络框架进行封装,如Okhttp、Volley、Retrofit等等。封装是为了更符合我们的项目需求,方便调用,这一步可能少不了,那么我们只需要思考怎么样才能做到任意切换网络框架呢?如果能够随意切换最好。

    其实我们请求的数据的时候基本是类似的无非就是获取数据和显示数据,可问题就在于各大网络框架的套路不一样,所以只要解决这个问题就好了。那么这个时候我们只需要自己搞一个套路就好,我们Activity ->自己的套路 ->第三大网络框架遵循我们的的套路->第三大网络框架,但是这样是不是会有问题呢?可能会有些许问题,毕竟不是直接的血缘关系,但是只要代码好扩展,随着项目的推进是很好完善的。

    自定义引擎类图.png

    3. 实现


    自定义一套规则,目前可以简单点,当然也可以根据项目需求稍微复杂点 IHttpEngine:

    /**
     * Created by Darren on 2017/03/01
     * Email: 240336124@qq.com
     * Description: 网络引擎的规范
     */
    public interface HttpEngine {
        // post 提交
        public void post(Context context, String url, Map<String, Object> params, HttpCallBack httpCallBack, boolean cache);
    
        // get 提交
        public void get(Context context, String url, Map<String, Object> params, HttpCallBack httpCallBack, boolean cache);
    
        // 取消请求
        // 下载文件
        // 上传文件
        // https添加安全证书
    }
    
    

    定义自己的套路HttpUtils:

    /**
     * Created by Darren on 2017/03/01
     * Email: 240336124@qq.com
     * Description:
     */
    public class HttpUtils {
        // 上下文
        private Context mContext;
        // 网络访问引擎
        private static HttpEngine mHttpEngine = new OkHttpEngine();
        // 接口地址
        private String mUrl;
        // 请求参数
        private Map<String, Object> mParams;
        // get请求标识
        private final int GET_REQUEST = 0x0011;
        // post请求标识
        private final int POST_REQUEST = 0x0022;
        // 请求的方式
        private int mRequestMethod = GET_REQUEST;
    
        // 是否缓存
        private boolean mCache = false;
    
        // 切换引擎
        public void exchangeEngine(HttpEngine httpEngine){
            this.mHttpEngine = httpEngine;
        }
    
        // 可以在Application中配置HttpEngine 
        public static initEngine(HttpEngine httpEngine){
             this.mHttpEngine = httpEngine;
       }
    
        private HttpUtils(Context context) {
            this.mContext = context;
            mParams = new HashMap<>();
        }
    
        public static HttpUtils with(Context context) {
            return new HttpUtils(context);
        }
    
        public HttpUtils url(String url) {
            mUrl = url;
            return this;
        }
    
        // 执行方法
        public void execute(HttpCallBack httpCallBack) {
            if (TextUtils.isEmpty(mUrl)) {
                throw new NullPointerException("访问路径不能为空");
            }
    
            if (mRequestMethod == GET_REQUEST) {
                get(mUrl, mParams, httpCallBack);
            }
    
            if (mRequestMethod == POST_REQUEST) {
                post(mUrl, mParams, httpCallBack);
            }
        }
    }
    

    封装一个简单的事例OkhttpEnigne:

    /**
     * Created by Darren on 2017/03/01
     * Email: 240336124@qq.com
     * Description: OKHttp引擎
     */
    public class OkHttpEngine implements HttpEngine {
    
        private static OkHttpClient mOkHttpClient = new OkHttpClient();
    
        @Override
        public void post(final Context context, String url, Map<String, Object> params, final HttpCallBack httpCallBack, final boolean cache) {
            // 省略部分代码......
            RequestBody requestBody = appendBody(params);
            Request request = new Request.Builder()
                    .url(url)
                    .tag(context)
                    .post(requestBody)
                    .build();
    
            mOkHttpClient.newCall(request).enqueue(
                    new Callback() {
                        @Override
                        public void onFailure(Call call, final IOException e) {
                            executeError(httpCallBack, e);
                        }
    
                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            String resultJson = response.body().string();
                            executeSuccessMethod(httpCallBack, resultJson);
                            // 缓存处理,下一期我们没事干,自己手写数据库框架
                        }
                    }
            );
        }
        
        /**
        *  执行成功的方法
        **/
        private void executeSuccessMethod(final HttpCallBack httpCallBack, final String resultJson) {
                try {
                    HttpUtils.handler.post(new Runnable() {
                        @Override
                        public void run() {
                            httpCallBack.onSucceed(resultJson);
                        }
                    });
                } catch (Exception e) {
                    executeError(httpCallBack, e);
                    e.printStackTrace();
                }
        }
        
        /**
        *  执行失败的方法
        */
        private void executeError(final HttpCallBack httpCallBack, final Exception e) {
                HttpUtils.handler.post(new Runnable() {
                    @Override
                    public void run() {
                        httpCallBack.onError(e);
                    }
                });
        }
    
        @Override
        public void get(Context context, String url, Map<String, Object> params, final HttpCallBack httpCallBack, boolean cache) {
            // 省略部分代码......
            Request.Builder requestBuilder = new Request.Builder().url(url).tag(context);
            Request request = requestBuilder.build();
            mOkHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                        httpCallBack.onError(e);
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String resultJson = response.body().string();
                    // 当然有的时候还需要不同的些许处理
                    HttpUtils.handler.post(new Runnable() {
                        @Override
                        public void run() {
                           httpCallBack.onSucceed(result);
                        }
                   });
                }
            });
        }
    

    我们可以自己试试Retrofit的方式,这里我就不写了,毕竟很多人对于Retrofit并不是特别了解。自己也希望可以从RxJava开始写文章然后一步一步的上升到Retrofit。总之现在已经有了一个默认的OkHttpEngine了,如果需要配置或者切换我们需要去自定义一个引擎,然后切换到当前引擎就可以了,我们看一下怎么使用:

     HttpUtils.with(context)
         .exchangeEngine(new RetrofitEngine());// 切换成Retrofit引擎
         .url(UrlConstant.CITY_MAIN_PAGE) // 路径
         .addParam("city", mCurrentCity)  // 添加参数
         .cache(true)  // 需要读缓存
         .post()  // post提交
         .execute(new HttpCallBack<CityFragmentEntity>() {
                 @Override
                public void onError(Exception e) {
                        // 错误回调
                }
    
                @Override
                public void onSucceed(CityFragmentEntity result) {
                       // result  返回的解析好的对象  可以直接操作不需要再Json解析
                       // 成功的回调
                }
         });
    

    这其实也没什么就是方便以后如果有了更好的第三方网络框架那么我们可以在Application中配置引擎,也可以每次请求的时候指定不同的引擎,这其实就是面向接口编程而已,这里还遗留了一个问题就是数据缓存,下一期我们需要利用面向对象的思想自己动手去写一套数据库封装,我们得按需定制把数据库写到外部存储卡中,还需要考虑数据库加密,Query懒加载,Lucene辅助搜索等等等等,不光是为了造轮子而是为了更好的了解其他数据库框架的原理。

    所有分享大纲:2017Android进阶之路与你同行

    视频讲解地址:http://pan.baidu.com/s/1pKWuZrX

    相关文章

      网友评论

      • 花季浅忆:Rxjava+ Retrofit + Okhttp不适合这种模式
        红橙Darren:@CJ行走在黎明 适配器用来适配 RxJava
        花季浅忆:@红橙Darren Retrofit已经是通过接口来使用了,而且他的每一个方法上面对应一个URL,适配器模式实现起来感觉也有点勉强啊:joy:
        红橙Darren:@CJ行走在黎明 👍👍 retrofit的思想就是解耦和封装,可以尝试参考用 adapter 去适配,后面我其实也有提到😬
      • sweetying:okhttp配置缓存拦截器可以实现缓存功能啊
      • onlyxing:请问这个有完整demo可以给我看看吗?
        HttpUtils中get(mUrl, mParams, httpCallBack);这个是怎么定义的
      • AWeiLoveAndroid:楼主,我也写了一个网络框架解耦的库,欢迎指教,我用的是代理模式+策略模式做的一个解耦方案,就是我调用的代码一行都不需要改动,只需要在application配置的时候改一下,就可以切换网络库了,比你的那个更灵活一些。https://github.com/AweiLoveAndroid/HttpRequestProcessor 这是代码地址,你可以去看看
        花季浅忆:你这叫比博主写的好???????
      • 少一点:学习了,厉害了,我的哥
      • 木子而东:根绝Rxjava和Retrofit不适合这种的
      • 我是少年520:老板,视屏为什么不能看
        我是少年520: @红橙Darren 可以了,手机保存到自己网盘就可以看了,谢谢老板。
        红橙Darren: @GoFastOrGoFar 我重新分享一下,谢谢提醒
      • Sky_Blue:想问一下,如果回调的泛型是List<Object>能不能解析出来??
        Sky_Blue:@红橙Darren OK
        红橙Darren: @刘付文 要自己定义解析回调类
      • 九尾猿:博主,文章中的贴出的httpUtils有问题吧,似乎有缺失:stuck_out_tongue_winking_eye:
      • 梦华芳秋:写代码和写文章是想通的,思想很重要!点赞,大神!
      • android0226:不错,思想很重要
      • e20c20d10d55:大神厉害吧
      • 如今美好:打算入手这一块,新人跟随大神的步伐😀
      • 东东wyd:大神
        红橙Darren:@东东wyd 真的不是
      • OliverBuddy:正需要这方面的资料 谢谢了
        红橙Darren: @OliverBuddy 😀😀😀
      • Android之路:厉害了,我的哥! 给你点赞:smile:
        红橙Darren: @Android之路 😄😄😄
      • 香脆的大鸡排:我可以理解成二次解藕第三方网络请求吗?
        香脆的大鸡排:@红橙Darren 思想很重要!:+1:
        红橙Darren: @香脆的大鸡排 是的😁,其实也没什么

      本文标题:Android链式调用 - 打造第三方的网络引擎

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