学习笔记之-----OkHttp之使用与简单封装

一.OKHttp的简单使用:

1.简意:OKHttp是一个高效的Http库

2.优点:

(1)支持SPDY,共享同一个Socket来处理同一个服务器的所有请求

(2)如果SPDY不可用,则通过连接池来减少请求延时

(3)无缝的支持GZIP来减少数据流量

(4)缓存响应数据来减少重复的网络请求

3.支持情况:

(1)一般的get请求

(2)一般的post请求

(3)基于Http的文件上传

(4)文件下载

(5)加载图片

(6)支持请求回调,直接返回对象和对象集合

(7)支持session的保持

4.基本使用步骤:

(1)在gradle中引入依赖库:

compile 'com.squareup.okhttp:okhttp:2.7.2'

(2)Http Get请求:

    private Object getDataFromUrl(String strUrl) {
        //(1)创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient();
        //(2)new 一个Request.Builder(),并设置其url(字符串),和build()方法
        Request request = new Request.Builder()
                .url(strUrl)
                .build();
        try {
            //(3)调用client.newCall(request对象).execute()方法,返回一个Response对象
            //这里要进行异常处理
            //execute()是同步处理
            Response response = client.newCall(request).execute();
            //(4)调用response.isSuccessful()方法判断返回是否成功
            if(response.isSuccessful()) {
                //(5)调用response.body().xxx()方法返回相应数据
                return response.body().string();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

但,execute()方法时同步操作,故而可调用其异步操作:enqueue()方法:

    private void getDataFromUrl(String strUrl) {
        //(1)创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient();
        //(2)new 一个Request.Builder(),并设置其url(字符串),和build()方法
        Request request = new Request.Builder()
                .url(strUrl)
                .build();
        //(3)调用client.newCall(request对象).enqueue(new Callback(){})方法
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                
            }
            @Override
            public void onResponse(Response response) throws IOException {
                    //(4)处理数据
                     response.body().string();      
            }
        });
    }

如:例子1:获取网络一张图片并显示出来:

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
        <ImageView
            android:id="@+id/test_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
</LinearLayout>

测试类:

public class TestActivity extends AppCompatActivity {
    private ImageView mImageView;       //定义图片

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        findViewID();           //绑定id

        requestImage();         //请求图片
    }

    /**
     * 为控件绑定id
     */
    private void findViewID() {
        mImageView = (ImageView) this.findViewById(R.id.test_img);
    }

    /**
     * 请求图片
     */
    private void requestImage() {
        //图片网址
        String mUrl = "http://p2.so.qhimgs1.com/t011b5b943d48cb7aae.jpg";
        //(1)创建OKHttpClient对象
        OkHttpClient client = new OkHttpClient();
        //(2)new 一个Request.Builder()对象,并设置url,和执行build()方法
        Request request = new Request.Builder()
                .url(mUrl)
                .build();

        //(3)调用client.newCall(request).enqueue(new Callback(){})方法
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                Log.d("TestActivity", " requestFaiure");
            }

            @Override
            public void onResponse(Response response) throws IOException {
                Log.d("TestActivity", " requestFaiure");
                //获取输入流对象
                InputStream is = response.body().byteStream();
                //转化为Bitmap对象
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                //为控件设置图片
                mImageView.setImageBitmap(bitmap);
            }
        });
    }
}

记得添加网络权限,然后一张美女图就出来了

(3)Http Post请求:

与Get类似,只是在创建OKHttpClient之后,需要创建一个RequestBody对象:

    RequestBody body = new FormEncodingBuilder()
            .add("type", "1")
            .build();
其中:add()可以有多个,即:参数名和参数值

如某个数据网址为:http://www.xxxxx.list?type=1

另一个数据网址为:http://www.xxxxx.list?type=2

......

这时就可以定义String strUrl = "http://www.xxxxx.list"

然后:

    RequestBody body = new FormEncodingBuilder()
        .add("type", "1")
        .add("type", "2")    
        .build();
就把这两个数据都添加了

记得还要在Request.Builder()添加post(body)

    Request request = new Request.Builder()
            .url(strUrl)
            .post(body)
            .build();

其它与get相同即可

(4)我们还可以利用handler在onResponse()方法中进行结果回传:

    @Override
    public void onResponse(Response response) throws IOException {
        if (response.isSuccessful()) {

            Message msg = new Message();
            msg.what = 1;
            msg.obj = response.body().string();
            mHandler.sendMessage(msg);
        }
    } 

二,OkHttp的简单封装:

(1)使用单例模式

(2)对get和post方法进行封装(把共同代码抽出来封装)

(3)对外公开静态方法:如post,get

(4)Callback基类,对OKHttp的回调进行封装。

这个类用里面有一个type,是方便回调中使用Gson对JSON进行解析的封装。

使用Callback的时候只需要在泛型中传入类似Data 、List<Data>即可以方便地使用JSON。
(5)由于原来的回调不在主线程,因此我们需要使用Handler来将回调放入主线程。

例子:

/**OkHttpClient类的封装
 * Created by maiyu on 2017/2/25.
 */

/**
 * 这个类用来辅助OKHttp
 */
public class OkHttpHelper {

    private static OkHttpHelper mOkHttpHelperInstance;      //定义OkHttpHelper对象
    private static OkHttpClient mClientInstance;            //定义OkHttpClient对象
    private Handler mHandler;                               //定义Handler对象
    private Gson mGson;                                     //定义Gson对象

    /**
     * 单例模式,私有构造函数,构造函数里面进行一些初始化
     */
    private OkHttpHelper() {
        //初始化OkHttpClient对象
        mClientInstance = new OkHttpClient();

        //设置连接超时,读取超时,写入超时
        mClientInstance.setConnectTimeout(10, TimeUnit.SECONDS);
        mClientInstance.setReadTimeout(10, TimeUnit.SECONDS);
        mClientInstance.setWriteTimeout(30, TimeUnit.SECONDS);
        //初始化Gson对象
        mGson = new Gson();

        //初始化Handler对象:传入Looper.getMainLooper
        mHandler = new Handler(Looper.getMainLooper());
    }

    /**
     * 获取实例
     * @return
     */
    public static OkHttpHelper getInstance() {

        //判空
        if (mOkHttpHelperInstance == null) {

            synchronized (OkHttpHelper.class) {
                if (mOkHttpHelperInstance == null) {
                    //初始化OkHttpHelper的实例
                    mOkHttpHelperInstance = new OkHttpHelper();
                }
            }
        }
        return mOkHttpHelperInstance;
    }

    /**
     * 封装一个request方法:以供get和post调用
     */
    public void request(final Request request, final BaseCallback callback) {

        //在请求之前所做的事,比如弹出对话框等
        // callback.onBeforeRequest(request);
        //调用OkHttpClient的newCall(request).enqueue方法,去重写
        mClientInstance.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                //返回失败的处理
                callbackFailure(request, callback, e);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (response.isSuccessful()) {
                    //返回成功回调:这里可以添加我们需要常用数据类型,如字符串
                    String resString = response.body().string();

                    if (callback.mType == String.class) {
                        //如果我们需要返回String类型
                        callbackSuccess(response, resString, callback);
                    } else {
                        //如果返回的是其他类型,则利用Gson去解析
                        try {
                            //获取Object对象o
                            Object o = mGson.fromJson(resString, callback.mType);
                            callbackSuccess(response, o, callback);
                        } catch (JsonParseException e) {
                            e.printStackTrace();
                            callbackError(response, callback, e);
                        }
                    }

                } else {
                    //返回错误
                    callbackError(response, callback, null);
                }
            }
        });
    }

    /**
     * 在主线程中执行的回调
     *
     * @param response
     * @param o
     * @param callback
     */
    private void callbackSuccess(final Response response, final Object o, final BaseCallback callback) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                callback.onSuccess(response, o);
            }
        });
    }

    /**
     * 在主线程中执行的回调
     * @param response
     * @param callback
     * @param e
     */
    private void callbackError(final Response response, final BaseCallback callback, final Exception e) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                callback.onError(response, response.code(), e);
            }
        });
    }

    /**
     * 在主线程中执行的回调
     * @param request
     * @param callback
     * @param e
     */
    private void callbackFailure(final Request request, final BaseCallback callback, final Exception e) {
        //发送一个Handler对象
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                callback.onFailure(request, e);
            }
        });
    }

    /**
     * get请求方法
     *
     * @param url
     * @param callback
     */
    public void get(String url, BaseCallback callback) {
        //get请求,不需要.post(body)---null
        Request request = buildRequest(url, null, HttpMethodType.GET);
        request(request, callback);
    }

    /**
     * post请求方法
     * @param url
     * @param params :body组合
     * @param callback
     */
    public void post(String url, Map<String, String> params, BaseCallback callback) {
        //根据url,body数据,和post标志发送请求得到,Request对象
        Request request = buildRequest(url, params, HttpMethodType.POST);
        request(request, callback);         //request请求
    }

    /**
     * 根据type:判断是get还是post请求
     * 构建请求对象
     * @param url
     * @param params
     * @param type
     * @return
     */
    private Request buildRequest(String url, Map<String, String> params, HttpMethodType type) {
        //创建Request.Builder对象
        Request.Builder builder = new Request.Builder();
        //为builder添加url
        builder.url(url);
        if (type == HttpMethodType.GET) {
            builder.get();          //get请求
        } else if (type == HttpMethodType.POST) {
            //post请求需要先post(body)
            builder.post(buildRequestBody(params));
        }
        return builder.build(); //返回builder.build
    }

    /**
     * 通过Map的键值对构建请求对象的body
     *即:post请求需要为builder添加body
     * @param params
     * @return
     */
    private RequestBody buildRequestBody(Map<String, String> params) {
        //创建FormEncodingBuilder对象
        FormEncodingBuilder builder = new FormEncodingBuilder();

        //遍历要传入的Map<String,String>组合,添加到body中去
        if (params != null) {
            for (Map.Entry<String, String> entity : params.entrySet()) {
                builder.add(entity.getKey(), entity.getValue());
            }
        }
        return builder.build();         //返回builder.build()方法
    }

    /**
     * 这个枚举用于指明是哪一种提交方式
     */
    enum HttpMethodType {
        GET,
        POST
    }

}

这里的BaseCallBack类:

public abstract class BaseCallback <T> {


    public   Type mType;

    static Type getSuperclassTypeParameter(Class<?> subclass)
    {
        Type superclass = subclass.getGenericSuperclass();
        if (superclass instanceof Class)
        {
            throw new RuntimeException("Missing type parameter.");
        }
        ParameterizedType parameterized = (ParameterizedType) superclass;
        return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
    }


    public BaseCallback()
    {
        mType = getSuperclassTypeParameter(getClass());
    }



    public  abstract void onBeforeRequest(Request request);


    public abstract  void onFailure(Request request, Exception e) ;


    /**
     *请求成功时调用此方法
     * @param response
     */
    public abstract  void onResponse(Response response);

    /**
     *
     * 状态码大于200,小于300 时调用此方法
     * @param response
     * @param t
     * @throws IOException
     */
    public abstract void onSuccess(Response response,T t) ;

    /**
     * 状态码400,404,403,500等时调用此方法
     * @param response
     * @param code
     * @param e
     */
    public abstract void onError(Response response, int code,Exception e) ;

}

使用:

(1)创建单例实例

private OkHttpHelper httpHelper  = OkHttpHelper.getInstance();

(2)直接调用get或者post方法
httpHelper.get(相应参数...)

httpHelper.post(相应参数..)












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值