Android 网络操作库 okhttp

现在Android网络方面的第三方库很多,volley,Retrofit,OKHttp等,各有各自的特点。okhttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势 。

okhttp官网

githubhttps://github.com/square/okhttp

一、 使用教程

使用之前,先在在app module build.gradle配置:

compile 'com.google.code.gson:gson:2.2.4'

1. Http Get请求

Request request = new Request.Builder().url("https://www.baidu.com").build();
        OkHttpClient client = new OkHttpClient();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            /**
             * 此时还在非UI线程中
             * @param call
             * @param response
             * @throws IOException
             */
            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });
2. Http Post请求
OkHttpClient client = new OkHttpClient();
        FormBody.Builder builder = new FormBody.Builder();
        builder.add("mb", "19811230100").add("pwd", "999999q");
        Request request = new Request.Builder().url("").post(builder.build()).build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            /**
             * 此时还在非UI线程中
             * @param call
             * @param response
             * @throws IOException
             */
            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });

二、封装

OKHttpException.java

package com.jackie.sample.okhttp.exception;

/**
 * Created by Administrator on 2016/10/30.
 */

public class OkHttpException extends Exception {
    private static final long serialVersionUID = 1L;

    /**
     * the server return code
     */
    private int ecode;

    /**
     * the server return error message
     */
    private Object emsg;

    public OkHttpException(int ecode, Object emsg) {
        this.ecode = ecode;
        this.emsg = emsg;
    }

    public Object getEmsg() {
        return emsg;
    }

    public void setEmsg(Object emsg) {
        this.emsg = emsg;
    }

    public int getEcode() {
        return ecode;
    }

    public void setEcode(int ecode) {
        this.ecode = ecode;
    }
}
DisposeDataHandler.java
package com.jackie.sample.okhttp.listener;

/**
 * Created by Administrator on 2016/10/30.
 */

public class DisposeDataHandler {
    public DisposeDataListener mListener = null;
    public Class<?> mClazz = null;

    public DisposeDataHandler(DisposeDataListener listener) {
        mListener = listener;
    }

    public DisposeDataHandler(DisposeDataListener listener, Class<?> clazz) {
        mListener = listener;
        mClazz = clazz;
    }
}
DisposeDataListener.java
package com.jackie.sample.okhttp.listener;

/**
 * Created by Administrator on 2016/10/30.
 */

public interface DisposeDataListener {
    void onSuccess(Object response);

    void onFailure(Object error);
}
CommonRequest.java
package com.jackie.sample.okhttp.request;

import java.io.File;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * Created by Administrator on 2016/10/30.
 * 负责创建各种类型的请求对象,包括get,post,文件上传类型,文件下载类型
 */

public class CommonRequest {

    /**
     * append the params to the url
     */
    public static Request createGetRequest(String url, RequestParams params) {
        StringBuilder urlBuilder = new StringBuilder(url).append("?");
        if (params != null) {
            for (Map.Entry<String, String> entry : params.urlParams.entrySet()) {
                urlBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }

        return new Request.Builder().url(urlBuilder.substring(0, urlBuilder.length() - 1)).get().build();
    }

    /**
     * create the key-value Request
     * @param url
     * @param params
     * @return
     */
    public static Request createPostRequest(String url, RequestParams params) {
        FormBody.Builder builder = new FormBody.Builder();
        if (params != null) {
            for (Map.Entry<String, String> entry : params.urlParams.entrySet()) {
                builder.add(entry.getKey(), entry.getValue());
            }
        }

        FormBody body = builder.build();
        return new Request.Builder().url(url).post(body).build();
    }

    /**
     * 文件上传请求
     */
    private static final MediaType FILE_TYPE = MediaType.parse("application/octet-stream");

    public static Request createMultiPostRequest(String url, RequestParams params) {
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        if (params != null) {
            for (Map.Entry<String, Object> entry : params.fileParams.entrySet()) {
                if (entry.getValue() instanceof File) {
                    builder.addPart(MultipartBody.Part.createFormData(entry.getKey(),
                            null,
                            RequestBody.create(FILE_TYPE, (File) entry.getValue())));
                } else {
                    builder.addFormDataPart(entry.getKey(), String.valueOf(entry.getValue()));
                }
            }
        }
        return new Request.Builder().url(url).post(builder.build()).build();
    }
}
RequestParams.java
package com.jackie.sample.okhttp.request;

import java.io.File;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by Administrator on 2016/10/30.
 */

public class RequestParams {
    public ConcurrentHashMap<String, String> urlParams = new ConcurrentHashMap<>();
    public ConcurrentHashMap<String, Object> fileParams = new ConcurrentHashMap<>();

    /**
     * Constructs a new empty { @code RequestParams } instance.
     */
    public RequestParams() {
        this((Map<String, String>) null);
    }

    /**
     * Constructs a new RequestParams instance containing the key/value string
     * params from this specified map.
     *
     * @param source
     *           the source key/value string map to add.
     */
    public RequestParams(Map<String, String> source) {
        if (source != null) {
            for (Map.Entry<String, String> entry : source.entrySet()) {
                put(entry.getKey(), entry.getValue());
            }
        }
    }

    public void put(String key, String value) {
        urlParams.put(key, value);
    }

    public void put(String key, File file) {
        fileParams.put(key, file);
    }
}
CommonJsonCallback.java
package com.jackie.sample.okhttp.response;

import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.jackie.sample.okhttp.exception.OkHttpException;
import com.jackie.sample.okhttp.listener.DisposeDataHandler;
import com.jackie.sample.okhttp.listener.DisposeDataListener;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

/**
 * Created by Administrator on 2016/10/30.
 */

/**
 * 专门处理Json的回调
 */
public class CommonJsonCallback implements Callback {
    /**
     * the logic layer exception, may alter in different app
     */
    protected final String RESULT_CODE = "ecode"; //有返回则对于http请求来说是成功的,但还有可能失败
    protected final int RESULT_CODE_VALUE = 0;
    protected final String ERROR_MSG = "emsg";
    protected final String EMPTY_MSG = "";

    /**
     * the java layer exception, do not same to the logic error
     */
    protected final int NETWORK_ERROR = -1;  //the network relative error
    protected final int JSON_ERROR = -2;  //the json relative error
    protected final int OTHER_ERROR = -3;  //the unknown error

    private DisposeDataListener mListener;
    private Class<?> mClazz;
    private Handler mHandler;

    public CommonJsonCallback(DisposeDataHandler handler) {
        mListener = handler.mListener;
        mClazz = handler.mClazz;
        mHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void onFailure(Call call, final IOException e) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mListener != null) {
                    mListener.onFailure(e);
                }
            }
        });
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        //还在子线程中
        final String result = response.body().toString();
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                handleResponse(result);
            }
        });
    }

    private void handleResponse(String result) {
        if (TextUtils.isEmpty(result)) {
            if (mListener != null) {
                mListener.onFailure(new OkHttpException(NETWORK_ERROR, EMPTY_MSG));
                return;
            }
        }

        try {
            JSONObject resultJsonObject = new JSONObject(result);
            if (resultJsonObject.has(RESULT_CODE)) {
                if (resultJsonObject.optInt(RESULT_CODE) == RESULT_CODE_VALUE) {
                    if (mClazz == null) {
                        if (mListener != null) {
                            mListener.onSuccess(resultJsonObject);
                        }
                    } else {
                        Gson gson = new Gson();
                        Object resultObject = gson.fromJson(result, mClazz);

                        if (resultObject == null) {
                            if (mListener != null) {
                                mListener.onFailure(new OkHttpException(JSON_ERROR, EMPTY_MSG));
                            }
                        } else {
                            //相应真正正确的处理,并且直接返回了实体对象
                            if (mListener != null) {
                                mListener.onSuccess(resultObject);
                            }
                        }
                    }
                }
            } else {
                if (mListener != null) {
                    mListener.onFailure(new OkHttpException(NETWORK_ERROR, EMPTY_MSG));
                }
            }
        } catch (JSONException e) {
            if (mListener != null) {
                mListener.onFailure(new OkHttpException(OTHER_ERROR, e.getMessage()));
            }
        }
    }
}
CommonOkHttpClient.java
package com.jackie.sample.okhttp;

/**
 * Created by Administrator on 2016/10/30.
 */

import com.jackie.sample.okhttp.listener.DisposeDataHandler;
import com.jackie.sample.okhttp.response.CommonJsonCallback;

import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;

/**
 * 用来发送get,post请求的工具类,包括设置一些请求的公用参数
 */
public class CommonOkHttpClient {
    private static final int TIME_OUT = 30;
    private static OkHttpClient mOkHttpClient;

    static {
        OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
        //对https的认证
        okHttpBuilder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
             return true;
          }
        });

        try {
            okHttpBuilder.connectTimeout(TIME_OUT, TimeUnit.SECONDS);
            okHttpBuilder.readTimeout(TIME_OUT, TimeUnit.SECONDS);
            okHttpBuilder.writeTimeout(TIME_OUT, TimeUnit.SECONDS);
            okHttpBuilder.followRedirects(true);

            SSLContext sslContext = SSLContext.getInstance("TLS");
            okHttpBuilder.sslSocketFactory(sslContext.getSocketFactory());

            mOkHttpClient = okHttpBuilder.build();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    public static void get(Request request, DisposeDataHandler handler) {
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new CommonJsonCallback(handler));
    }

    public static void post(Request request, DisposeDataHandler handler) {
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new CommonJsonCallback(handler));
    }
}
封装之后代码结构图如下:

Android 网络操作库 okhttp_第1张图片
封装之后,网络请求就简单多了,如下图:

Get请求

Android 网络操作库 okhttp_第2张图片

Post请求

Android 网络操作库 okhttp_第3张图片Android 网络操作库 okhttp_第4张图片








你可能感兴趣的:(android,okhttp)