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

本项目来自菜鸟窝,有兴趣者点击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方法进行操作。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容