okhttp3 使用详解及简单封装

okhttp一个处理网络请求的开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献,用于替代HttpUrlConnection和Apache HttpClient。
目前已经更新到了okhttp3,相对与之前的2变动的还是比较的大,
okhttp直接newOkHttpClient,而okhttp3中提供了Builder,使用了创建者设计模式,

OkHttpClient参数的配置:之前参数可以直接OkHttpClient.setConnectTimeout()设置,现在OkHttpClient使用创建者模式,需要在OkHttpClient.Builder上设置可配置的参数:

new OkHttpClient.Builder().connectTimeout();

okhttp调用OkHttpClient的setCookieHandler方法,CookieHandler 的子类CookieManager实现了cookie的具体管理方法,okhttp3中已经没有setCookieHandler方法了,而改成了cookieJar,需要在OkHttpClient的Builder的cookieJar方法中设置。

post请求:
okhttp使用MultipartBuilder,FormEncodingBuilder构建post消息体,最终构建出来的都是RequestBody,而okhttp3增加了RequestBody的子类,构造器放到了RequestBody的子类中,MultipartBody.Builder既可以添加表单数据,也可以添加文件等二进制数据。

回调方法Callback在3.0之后变为了:void onFailure(Call call, IOException e),void onResponse(Call call, Response response)。

导入:
compile 'com.squareup.okhttp3:okhttp:3.3.0'

简单使用方法:
首先,如果要设置设置超时时间和缓存,要通过OkHttpClient.Builder来设置,

OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
OkHttpClient okHttpClient=builder.build();
get请求:

OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
    .url(url)
    .build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
		System.out.println(response.body().string());
            }
        });
response的body有很多种输出方法,string()只是其中之一,注意是string()不是toString()。如果是下载文件就是response.body().bytes()。
另外可以根据response.code()获取返回的状态码。

post请求:
post提交普通的表单:如登录..

OkHttpClient okHttpClient = new OkHttpClient();
RequestBody body = new FormBody.Builder()
    .add("键", "值")
    .add("键", "值")
    .build();
Request request = new Request.Builder()
    .url(url)
    .post(body)
    .build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {...}

RequestBody的数据格式都要指定Content-Type,常见的有三种:

application/x-www-form-urlencoded 数据是个普通表单
multipart/form-data 数据里有文件
application/json 数据是个json
上边的普通表单并没有指定Content-Type,这是因为FormBody继承了RequestBody,它已经指定了数据类型为application/x-www-form-urlencoded。

post提交json数据:

public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, "你的json数据");
Request request = new Request.Builder()
    .url(url)
    .post(body)
    .build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {...}
post上传文件:
先定义上传文件类型:

public static final MediaType MEDIA_TYPE_MARKDOWN
            = MediaType.parse("text/x-markdown; charset=utf-8");

OkHttpClient okHttpClient = new OkHttpClient();
 File file = new File("/sdcard/xxx.txt");
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
                .build();
call.enqueue(new Callback() {...}
post上传文件并传入其他类型的字段:

public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
OkHttpClient okHttpClient = new OkHttpClient();
 File file = new File("/sdcard/xxx.txt");
RequestBody requestBody = new MultipartBody.Builder()
            .addFormDataPart("token","token")
            .addFormDataPart("file", file.getName(), RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
            .build();
Request request = new Request.Builder()
            .url(url)
            .post(requestBody)
            .build();
call.enqueue(new Callback() {...}
异步下载:

	OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) {
                InputStream inputStream = response.body().byteStream();
                FileOutputStream fileOutputStream = null;
                try {
                    fileOutputStream = new FileOutputStream(new File("/sdcard/xx.txt"));
                    byte[] buffer = new byte[2048];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, len);
                    }
                    fileOutputStream.flush();
                } catch (IOException e) {
                    e.printStackTrace();
               }
           }
       });
上面的都为异步请求,当然也支持同步的方式,同步的只要调用 call.execute()就可以了。

okhttp3的简单封装:

public class OkHttpClientManager {
    private static OkHttpClientManager mInstance;
    private OkHttpClient mOkHttpClient;
    private Handler mDelivery;
    private Gson mGson;

    private OkHttpClientManager()
    {
         OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder();
	okHttpClient.connectTimeout(5, TimeUnit.SECONDS);
        okHttpClient.readTimeout(5, TimeUnit.SECONDS);
        okHttpClient.cookieJar(new CookieJar() {
            private final HashMap<HttpUrl, List<Cookie>> cookieStore = new HashMap<>();
            @Override
            public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                cookieStore.put(url, cookies);
            }

            @Override
            public List<Cookie> loadForRequest(HttpUrl url) {
                return null;
            }
        });
        mOkHttpClient=okHttpClient.build();
        mDelivery = new Handler(Looper.getMainLooper());
        mGson = new Gson();
    }

    public static OkHttpClientManager getInstance()
    {
        if (mInstance == null)
        {
            synchronized (OkHttpClientManager.class)
            {
                if (mInstance == null)
                {
                    mInstance = new OkHttpClientManager();
                }
            }
        }
        return mInstance;
    }

     /**
     * 异步的get请求
     *
     * @param url
     * @param callback
     */
    private void _getAsyn(String url, final ResultCallback callback)
    {
        final Request request = new Request.Builder()
                .url(url)
                .build();
        deliveryResult(callback, request);
    }

    /**
     * 异步的post请求
     *
     * @param url
     * @param callback
     * @param params
     */
    private void _postAsyn(String url, final ResultCallback callback, Param... params)
    {
        Request request = buildPostRequest(url, params);
        deliveryResult(callback, request);
    }

    /**
     * 异步的post请求
     *
     * @param url
     * @param callback
     * @param params
     */
    private void _postAsyn(String url, final ResultCallback callback, Map<String, String> params)
    {
        Param[] paramsArr = map2Params(params);
        Request request = buildPostRequest(url, paramsArr);
        deliveryResult(callback, request);
    }

 private Param[] map2Params(Map<String, String> params)
    {
        if (params == null) return new Param[0];
        int size = params.size();
        Param[] res = new Param[size];
        Set<Map.Entry<String, String>> entries = params.entrySet();
        int i = 0;
        for (Map.Entry<String, String> entry : entries)
        {
            res[i++] = new Param(entry.getKey(), entry.getValue());
        }
        return res;
    }

 //*************对外公布的方法************

    //异步get请求
    public static void getAsyn(String url, ResultCallback callback)
    {
        getInstance()._getAsyn(url, callback);
    }
    //异步的post请求
    public static void postAsyn(String url, final ResultCallback callback, Param... params)
    {
        getInstance()._postAsyn(url, callback, params);
    }

    //异步的post请求
    public static void postAsyn(String url, final ResultCallback callback, Map<String, String> params)
    {
        getInstance()._postAsyn(url, callback, params);
    }

private void deliveryResult(final ResultCallback callback, Request request)
    {
        mOkHttpClient.newCall(request).enqueue(new Callback()
        {

            @Override
            public void onFailure(Call call, IOException e) {
                sendFailCallback(callback,e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                try
                {
                    final String string = response.body().string();
                    if (callback.mType == String.class)
                    {
                        sendSuccessCallBack(callback,string);
                    } else
                    {
                        Object o = mGson.fromJson(string, callback.mType);
                        sendSuccessCallBack(callback,string);
                    }

                } catch (IOException e)
                {
                    sendFailCallback(callback,e);
                } catch (com.google.gson.JsonParseException e)//Json解析的错误
                {
                    sendFailCallback(callback,e);
                }
            }
        });
    }
private void sendFailCallback(final ResultCallback callback, final Exception e) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                if (callback != null) {
                    callback.onFailure(e);
                }
            }
        });
    }

    private void sendSuccessCallBack(final ResultCallback callback, final Object obj) {
        mDelivery.post(new Runnable() {
            @Override
            public void run() {
                if (callback != null) {
                    callback.onSuccess(obj);
                }
            }
        });
    }

    private Request buildPostRequest(String url, Param[] params)
    {
        if (params == null)
        {
            params = new Param[0];
        }
        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        for (Param param : params)
        {
            formBodyBuilder.add(param.key, param.value);
        }
        RequestBody requestBody = formBodyBuilder.build();
        return new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
    }
public static abstract class ResultCallback<T>
    {
        Type mType;

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

        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]);
        }

        /**
         * 请求成功回调
         * @param response
         */
        public abstract void onSuccess(T response);

        /**
         * 请求失败回调
         * @param e
         */
        public abstract void onFailure(Exception e);
    }

    /**
     * post请求参数类
     */
    public static class Param
    {
        public Param()
        {
        }

        public Param(String key, String value)
        {
            this.key = key;
            this.value = value;
        }
        String key;
        String value;
    }

}






  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值