美文网首页Java 技术IT/互联网Android网络
仿京东商城系列3------封装Okhttp

仿京东商城系列3------封装Okhttp

作者: 小庄bb | 来源:发表于2017-08-22 17:50 被阅读473次

    本项目来自菜鸟窝,有兴趣者点击http://www.cniao5.com/course/

    项目已经做完,源码地址。https://github.com/15829238397/CN5E-shop

    仿京东商城系列0------项目简介
    仿京东商城系列1------fragmentTabHost实现底部导航栏
    仿京东商城系列2------自定义toolbar
    仿京东商城系列3------封装Okhttp
    仿京东商城系列4------轮播广告条
    仿京东商城系列5------商品推荐栏
    仿京东商城系列6------下拉刷新上拉加载的商品列表
    仿京东商城系列7------商品分类页面
    仿京东商城系列8------自定义的数量控制器
    仿京东商城系列9------购物车数据存储器实现
    仿京东商城系列10------添加购物车,管理购物车功能实现
    仿京东商城系列11------商品排序功能以及布局切换实现(Tablayout)
    仿京东商城系列12------商品详细信息展示(nativie与html交互)
    仿京东商城系列13------商品分享(shareSDK)
    仿京东商城系列14------用户登录以及app登录拦截
    仿京东长城系列15------用户注册,SMSSDK集成
    仿京东商城系列16------支付SDK集成
    仿京东商城系列17------支付功能实现
    仿京东商城系列18------xml文件读取(地址选择器)
    仿京东商城系列19------九宫格订单展示
    仿京东商城系列20------终章


    前言

    本文讲述Okhttp的封装过程,便于使用,不对源码部分进行深究。
    推荐一篇文章
    okhttp源码学习笔记(一)-- 综述

    内容

    基本使用

    • 设置网络权限
      在manifests文件中增加权限
     <uses-permission android:name="android.permission.INTERNET"/>
    
    • 添加依赖
         compile 'com.squareup.okhttp:okhttp-urlconnection:2.7.5'
        compile 'com.squareup.okhttp:okhttp:2.7.5'
    
    • get请求
     OkHttpClient client = new OkHttpClient() ;
            client.setConnectTimeout(5 , TimeUnit.SECONDS);
            client.setWriteTimeout(5 , TimeUnit.SECONDS);
            client.setReadTimeout(5 , TimeUnit.SECONDS);
    
            String url = "http://www.jianshu.com/p/6ffde18fb034" ;
    
            Request request = new Request.Builder().url(url).get().build() ;
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Request request, IOException e) {
                    
                }
    
                @Override
                public void onResponse(Response response) throws IOException {
    
                }
            });
        }
    
    • post请求
     OkHttpClient client = new OkHttpClient() ;
            client.setConnectTimeout(5 , TimeUnit.SECONDS);
            client.setWriteTimeout(5 , TimeUnit.SECONDS);
            client.setReadTimeout(5 , TimeUnit.SECONDS);
    
            String url = "http://www.jianshu.com/p/6ffde18fb034" ;
            //盛放参数
            RequestBody requestBody = new FormEncodingBuilder()
                    .add("name","xxx").build() ;
    
            Request request = new Request.Builder().url(url).post(requestBody).build() ;
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Request request, IOException e) {
    
                }
    
                @Override
                public void onResponse(Response response) throws IOException {
    
                }
            });
        }
    
    

    okhttp封装

    由上面的简单使用,我们可以知道Okhttp的使用有几个重要的部分:

    • client
    • Requset
    • Callback
      我们将从这三方面对Okhttp进行封装。
      先上代码:
    package com.example.cne_shop.okhttp;
    
    import android.app.Service;
    import android.os.Handler;
    import android.text.TextUtils;
    import android.util.Log;
    
    import com.example.cne_shop.myException.GET_RESPONSE_MESSAGE_FAILURE;
    import com.example.cne_shop.myException.GSON_ANALYZE_MESSAGE_FAILURE;
    import com.google.gson.Gson;
    import com.squareup.okhttp.Callback;
    import com.squareup.okhttp.FormEncodingBuilder;
    import com.squareup.okhttp.OkHttpClient;
    import com.squareup.okhttp.Request;
    import com.squareup.okhttp.RequestBody;
    import com.squareup.okhttp.Response;
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Created by 博 on 2017/8/22.
     */
    
    public class OkhttpHelper {
    
        //所有的请求公用一个OkhttpClient
        private static OkHttpClient client ;
        private Handler handler ;
        private Gson gson ;
    
        private static final int TOKEN_ERROR = 401 ;
        private static final int TOKEN_EXPRISE = 402 ;
        private static final int TOKEN_MISSING = 403 ;
    
        private OkhttpHelper(){
    
            //初始化client信息
            client = new OkHttpClient() ;
            client.setConnectTimeout(5 , TimeUnit.SECONDS);
            client.setWriteTimeout(5 , TimeUnit.SECONDS);
            client.setReadTimeout(5 , TimeUnit.SECONDS);
    
            gson = new Gson() ;
        }
    
        //提供一个静态方法供外部请求。
        public static OkhttpHelper getOkhttpHelper(){
            return new OkhttpHelper() ;
        }
    
        //提交get请求的方法。
        public void doGet (String uri , BaseCallback callback){
            doGet(uri , callback , null);
        }
    
        //带参数请求的方法
        public void doGet (String uri , BaseCallback callback , Map<String , String> formData){
            Request request = buildRequest(uri , METHOD_TYPE.GET , formData);
            doRequest(request , callback);
        }
    
        public void doPost(String uri , BaseCallback callback , Map<String , String> formData){
            Request request = buildRequest(uri , METHOD_TYPE.POST , formData);
            doRequest(request , callback);
        }
    
        private void doRequest(final Request request , final BaseCallback callback){
    
            callback.onRequestBefore();
    
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Request request, IOException e) {
                    //提交失败
                    callbackFailure(callback , request ,e);
                }
    
                @Override
                public void onResponse(Response response) throws IOException {
                    if (response.isSuccessful()){
                        String jqury = response.body().string() ;
    
                        if (callback.type == String.class){
                            callback.callBackSucces(response , jqury);
                        }else {
                            try{
                                Object object = gson.fromJson(jqury , callback.type) ;
                                callbackSuccess(callback , response , jqury);
                            }catch (Exception e){
                                callbackError(callback , response , null);
                                throw new GSON_ANALYZE_MESSAGE_FAILURE("gson解析信息失败") ;
                            }
                        }
                    }else{
                        callbackError(callback , response , null);
                    }
    
                }
            });
    
    
        }
    
        private Request buildRequest (String uri , METHOD_TYPE method_type , Map<String , String> formData){
    
            Request.Builder builder = new Request.Builder() ;
            if(method_type == METHOD_TYPE.GET){
    
                uri = getUriWithParams(uri , formData) ;
                builder.url(uri) ;
                builder.get() ;
    
            }else if (method_type == METHOD_TYPE.POST){
                builder.url(uri) ;
                RequestBody requestBody = buildFormData(formData) ;
                builder.post(requestBody) ;
            }
            return builder.build() ;
        }
    
        private RequestBody buildFormData (Map<String , String> formData){
    
            if(formData != null) {
                FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder() ;
                for (Map.Entry<String , String> objectMap : formData.entrySet()){
                    formEncodingBuilder.add( objectMap.getKey() , objectMap.getValue() ) ;
                }
    
                return formEncodingBuilder.build() ;
            }
            return null ;
        }
    
        //对参数进行处理
        private String getUriWithParams(String uri , Map<String , String > formData){
            String symbol = null ;
            int signNum = 0 ;
    
           if(formData == null){
               return uri ;
           }
    
            for(String key : formData.keySet()){
                symbol = (signNum++ == 0 )? "?" : "&" ;
                uri = uri+symbol+key+"="+formData.get(key) ;
            }
            return uri ;
        }
    
        /**
         * 以下方法保证对于okhttp的拦截处理运行在主线程
         *
         */
        private void callbackTokenError (final BaseCallback baseCallback , final Response response){
            handler.post(new Runnable() {
                @Override
                public void run() {
                    baseCallback.onTokenError(response , response.code());
                }
            });
        }
    
        private void callbackSuccess (final BaseCallback baseCallback , final Response response , final Object object){
            handler.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        baseCallback.callBackSucces(response , object);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        private void callbackError (final BaseCallback baseCallback , final Response response , final Object object){
            handler.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        baseCallback.onErroe(response , response.code() , new GET_RESPONSE_MESSAGE_FAILURE("获取服务器信息失败"));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        private void callbackFailure (final BaseCallback baseCallback , final Request request , final IOException e){
            handler.post(new Runnable() {
                @Override
                public void run() {
                    baseCallback.onFailure(request , e);
                }
            });
        }
    
    
    
        enum METHOD_TYPE {
            GET,
            POST
        }
    
        private void demo(){
    
            OkHttpClient client = new OkHttpClient() ;
            client.setConnectTimeout(5 , TimeUnit.SECONDS);
            client.setWriteTimeout(5 , TimeUnit.SECONDS);
            client.setReadTimeout(5 , TimeUnit.SECONDS);
    
            String url = "http://www.jianshu.com/p/6ffde18fb034" ;
            //盛放参数
            RequestBody requestBody = new FormEncodingBuilder()
                    .add("name","xxx").build() ;
    
            Request request = new Request.Builder().url(url).post(requestBody).build() ;
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Request request, IOException e) {
    
                }
    
                @Override
                public void onResponse(Response response) throws IOException {
    
                }
            });
        }
    
    }
    
    

    其中BaseCallBack类代码如下:

    package com.example.cne_shop.okhttp;
    
    import com.google.gson.internal.$Gson$Types;
    import com.squareup.okhttp.Request;
    import com.squareup.okhttp.Response;
    
    import java.io.IOException;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    
    /**
     * Created by 博 on 2017/8/22.
     */
    
    public abstract class BaseCallback<T> {
        public Type type ;
    
        static Type getSuperclassTypeParameter(Class<?> subclass ){
            Type superClass = subclass.getGenericSuperclass() ;
            if (superClass instanceof Class){
                throw new RuntimeException("Missing type parameter") ;
            }
            ParameterizedType parameterizedType = (ParameterizedType) superClass;
            return $Gson$Types.canonicalize(parameterizedType.getActualTypeArguments()[0]) ;
        }
    
    
    
        public BaseCallback(){
            this.type = getSuperclassTypeParameter(this.getClass()) ;
        }
    
        public abstract void onRequestBefore();
        public abstract void onFailure(Request request, IOException e) ;
        public abstract void onErroe(Response response , int responseCode , Exception e) throws IOException ;
        public abstract void callBackSucces(Response response , T t) throws IOException ;
        public abstract void onTokenError(Response response , int responseCode );
    
    }
    
    • 有关于getSuperclassTypeParameter()静态方法,作用为取得类泛型的类型。也就是得到T的真实类型。
      详细解释戳http://blog.csdn.net/hello__zero/article/details/44201033

    • 其中,我们定义了一个OkhttpClient对象,并设置伪静态,使得所有请求都使用这一个对象。

    • 利用枚举类型参数,将post与get请求的request构建分别进行操作。得到request类型对象

    • 自定义basecallback抽象类,插入Callback的实现方法中中进行实现,使得使用者能在使用时再实现相关的方法,且方法的执行被放在主线程。

    使用

    • 使用时只需要通过OkhttpHelper.getOkhttpHelper(),方法获得OkhttpHelper对象。
    • 使用OkhttpHelper对象调用doget,或dopost方法进行操作。

    相关文章

      网友评论

        本文标题:仿京东商城系列3------封装Okhttp

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