OKHTTP的简单封装

来源:互联网 发布:魔侠传 网络异常 编辑:程序博客网 时间:2024/05/17 04:01

前言

我们常用的网络框架大致有三个:Xutils,Volly,和OKhttp,前两个随着谷歌对OKhttp的推出基本上被取代了,既然被取代了,就肯定有它们的不足。
Xutils:博而不精,它包含的功能很多,像网络请求,加载图片,注解,数据库。。。这些导致它的包非常大,并且对我们框架的更新也比较困难。
Volly:速度快,但是不支持下载大文件,这个局限也就约束它的使用范围,以及框架的广度。
OKhttp:减少对服务器的请求次数,减少请求延迟,减少数据流量,缓存响应数据等来减少重复的网络请求,自动处理GZip压缩等,
但是OKhttp也不是没有缺点,那就是:实现代码比较多,并且传回来的消息需要切到主线程,而主线程要自己去写。传入调用比较复杂所以这里写了一个工具类进行简单的封装

封装的功能

使用Handler实现子线程和主线程之间的交互
定义三个接口调用分别返回String,byte[],和JSONObject
同时在支持表单提交Post 请求
复用Handler而不是一直实例化
依赖
使用之前当然是要导入依赖以及使用的网络权限
依赖

//    导入OK的网络请求框架    compile 'com.squareup.okhttp3:okhttp-ws:3.4.2'

网络权限

    <!--加入网络权限-->    <uses-permission android:name="android.permission.INTERNET"/>

工具类

import android.os.Handler;import org.json.JSONException;import org.json.JSONObject;import java.io.IOException;import java.util.Map;import okhttp3.Callback;import okhttp3.FormBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;/** * 尝试简单封装一下OKhttp */public class OKhttpManager {//定义成员变量    private OkHttpClient mClient;    private  volatile  static OKhttpManager sManager;//防止多个线程同时访问    private static Handler handler;//开启线程交互 这里的handler 是os包下面的//    使用构造方法,完成初始化    public OKhttpManager() {        mClient=new OkHttpClient();        handler=new Handler();    }//    使用单例模式,通过获取的方式拿到对象    public static  OKhttpManager getInstance(){        OKhttpManager instance=null;        if (sManager==null){            synchronized (OKhttpManager.class){                if (instance==null){                    instance=new OKhttpManager();                    sManager=instance;                }            }        }        return  instance;    }//    定义要调用的接口    interface  Func1{    void  onResponse(String result);}    interface Func2{        void onResponse(byte [] result);    }    interface Func3{        void  onResponse(JSONObject jsonObject);    }//    使编写的代码运行在主线程//    处理请求网络成功的方法,返回的结果是Json串    private static void onSuccessJsonStringMethod(final String jsonValue, final Func1 callBack){        handler.post(new Runnable() {            @Override            public void run() {                if (callBack!=null){                    try {                        callBack.onResponse(jsonValue);                    }catch (Exception e){                        e.printStackTrace();                    }                }            }        });    }    /**     * 返回响应的结果是Json对象     * @param jsonValue     * @param callBack     */    private void onSuccessJsonObjectMethod(final String jsonValue, final Func3 callBack){        handler.post(new Runnable() {            @Override            public void run() {                if (callBack!=null){                    try{                        callBack.onResponse(new JSONObject(jsonValue));                    }catch(JSONException e){                        e.printStackTrace();                    }                }            }        });    }    /**     * 返回响应的结果是byte[]数组     * @param data     * @param callBack     */    private void onSuccessByteMethod(final byte[] data,final Func2 callBack){        handler.post(new Runnable() {            @Override            public void run() {                if (callBack!=null){                    callBack.onResponse(data);                }            }        });    }//    然后是调用方法    /**     * 请求指定的url返回的结果是Json     * @param url     * @param callBack     */    public  void  asyncJsonStringByURL(String url,final Func1 callBack){        final  Request request = new Request.Builder().url(url).build();        mClient.newCall(request).enqueue(new Callback() {            @Override            public void onFailure(okhttp3.Call call, IOException e) {            }            @Override            public void onResponse(okhttp3.Call call, Response response) throws IOException {                if (response!=null&&response.isSuccessful()){                    onSuccessJsonStringMethod(response.body().string(),callBack);                }            }        });    }    /**     * 请求返回的是json对象     *     * @param url     * @param callBack     */    public void asyncJsonObjectByURL(String url, final Func3 callBack) {        final Request request = new Request.Builder().url(url).build();        mClient.newCall(request).enqueue(new Callback() {            @Override            public void onFailure(okhttp3.Call call, IOException e) {            }            @Override            public void onResponse(okhttp3.Call call, Response response) throws IOException {                if (response != null && response.isSuccessful()) {                    onSuccessJsonObjectMethod(response.body().string(), callBack);                }            }        });    }    /**     * 请求返回的是byte字节数组     */    public void asyncGetByteByURL(String url, final Func2 callBack) {        final Request request = new Request.Builder().url(url).build();        mClient.newCall(request).enqueue(new Callback() {            @Override            public void onFailure(okhttp3.Call call, IOException e) {            }            @Override            public void onResponse(okhttp3.Call call, Response response) throws IOException {                if (response != null && response.isSuccessful()) {                    onSuccessByteMethod(response.body().bytes(), callBack);                }            }        });    }//    表单提交像一般的姓名和密码    /**     * 表单提交     * @param url     * @param params     * @param callBack     */    public void sendComplexForm(String url, Map<String,String> params,final Func1 callBack){        FormBody.Builder form_builder=new FormBody.Builder();//表单对象包含以input开始的对象以html为主//        非空键值对        if (params != null && !params.isEmpty()) {            for(Map.Entry<String,String> entry : params.entrySet()){                form_builder.add(entry.getKey(),entry.getValue());            }        }        RequestBody request_body = form_builder.build();        Request request = new Request.Builder().url(url).post(request_body).build();//采用post方式提交        mClient.newCall(request).enqueue(new Callback() {            @Override            public void onFailure(okhttp3.Call call, IOException e) {            }            @Override            public void onResponse(okhttp3.Call call, Response response) throws IOException {                if (response!=null&&response.isSuccessful()){                    onSuccessJsonStringMethod(response.body().string(), callBack);                }            }        });    }}

以上就是工具类,用时直接复制粘贴到我们的工具类里面即可,
那如何调用呢?
其实调用也很简单,只需简单实例化

  private OKhttpManager manager = OKhttpManager.getInstance();

然后简单调用即可
在业务代码里

package jingou.jo.com.tryfengzhuangokhttp;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageView;import java.util.HashMap;import butterknife.BindView;import butterknife.ButterKnife;import butterknife.OnClick;public class MainActivity extends AppCompatActivity {    @BindView(R.id.json)    Button json;    @BindView(R.id.table)    Button table;    @BindView(R.id.pic)    Button pic;    @BindView(R.id.imgs)    ImageView imageView;    //        使用封装后的OKhttp,所定义的成员变量   private OKhttpManager manager = OKhttpManager.getInstance();    private String json_path="http://apiv4.yangkeduo.com/subject_collection/18?pdduid=";    private String pic_path="http://imgsrc.baidu.com/image/c0%3Dshijue1%2C0%2C0%2C294%2C40/sign=3d2175db3cd3d539d530078052ee8325/b7003af33a87e950c1e1a6491a385343fbf2b425.jpg";    private String post_path="http://blog.csdn.net/qiaoshi96_bk/article/details/77371035";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ButterKnife.bind(this);    }//设置点击事件    @OnClick({R.id.json, R.id.table, R.id.pic})    public void onViewClicked(View view) {        switch (view.getId()) {            case R.id.json://这里调用获取网络Json串封装的方法                manager.asyncJsonStringByURL(json_path, new OKhttpManager.Func1() {                    @Override                    public void onResponse(String result) {                        Log.e("TAG",result);                    }                });                break;            case R.id.table://                表单提交的方法向服务器提交账号或者是密码                final HashMap<String, String> map = new HashMap<>();                map.put("qs","1008611");                manager.sendComplexForm(post_path,map, new OKhttpManager.Func1() {                    @Override                    public void onResponse(String result) {                        Log.e("TAG"+map.getClass().getName(),result);                    }                });                break;            case R.id.pic://                获取图片使用Bitmap加载             manager.asyncGetByteByURL(pic_path, new OKhttpManager.Func2() {                 @Override                 public void onResponse(byte[] result) {                     Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);                     imageView.setImageBitmap(bitmap);                 }             });                break;        }    }}

这里的我是通过注解来实现获取id的非常好用贴上它的依赖:Butterknife(黄油刀)

//    查找id的依赖    compile 'com.jakewharton:butterknife:8.5.1'    annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'

具体用法:http://blog.csdn.net/qiaoshi96_bk/article/details/77371035
效果如下
这里写图片描述