欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

OKHTTP的简单封装

程序员文章站 2024-03-25 11:33:04
...

前言

我们常用的网络框架大致有三个: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
效果如下
OKHTTP的简单封装

相关标签: 网络 框架