一、简介
Android系统提供了两种HTTP通信类:HttpURLConnection和HttpClient,前者对比后者十分难用。
网络请求进化:HttpURLConnection --- Apache HttpClient --- Volley ---OKHttp
volley是google官方提供的网络请求框架,它依赖于httpclient,而在Android6.0的sdk中去掉了httpclient,因而okhttp更受欢迎。
从Android4.4开始HttpURLConnection的底层实现采用的是okHttp
二、特点
- 一般的get请求
- 一般的post请求
- 基于Http的文件上传
- 文件下载
- 加载图片
- 支持请求回调,直接返回对象、对象集合
- 支持session的保持
- 支持自签名网站https的访问,提供方法设置下证书就行
- 支持取消某个请求
三、OKHTTP的基本使用
1 引入依赖
compile 'com.squareup.okhttp3:okhttp:3.7.0'
2 使用前,认识一下核心类
- OKHttpClient 客户端对象
- Request是OKHttp中的请求,post请求中需要包含RequestBody
- Build是辅助类,用于生产对象
- Response是OKHttp中的响应,响应中可以得到返回是否成功,返回数据
- RequestBody请求数据,在Post请求中用到
- client.newCall(request).execute()同步请求
- client.newCall(request).enqueue(CallBack callback)异步请求,但是CallBack里面的代码实在子线程执行的,因此不能更新UI。需要配合Handle使用,更新UI。
3 基本使用步骤
3.1 创建OKHttpClient对象,官方推荐单例。
3.2 创建Request对象,这个对象是请求对象,需要指定URL。
如果是post请求,需要通过FormEncodingBuilder创建RequestBody对象,指定post传进去的参数。get不需要。
3.3 调用okhttpClient的newCall(request).enqueue(CallBack callback)或者execute方法。在callback的回调onResonse函数里做你需要做的事情。onResponse在子线程执行,如需更新UI,配合handler使用。
enqueue是异步请求,有回调接口,execute是同步请求,没有回调接口。一般使用异步请求。
四、基础封装
public class OKHttpHelper { private static OKHttpHelper mHelper = null; private static OkHttpClient mClient = null; private Handler mHandler; /** * 私有构造函数 */ private OKHttpHelper() { // 没有响应时使用超时结束call。没有响应的原因可能是客户点链接问题、服务器可用性问题或者这之间的其他东西。 mClient = new OkHttpClient().newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS).build(); mHandler = new Handler(Looper.getMainLooper()); } /** * 单例模式 获取实例 * * @return */ public static OKHttpHelper getInstance() { if (mHelper == null) { synchronized (OKHttpHelper.class) { if (mHelper == null) { mHelper = new OKHttpHelper(); } } } return mHelper; } /** * 对外公开的post方法 * <p> * post请求需要通过FormEncodingBuilder创建RequestBody对象,指定post传进去的参数 * * @param url 请求地址 * @param params 请求参数 * @param callBack 回调接口 * @param tag 请求标签 */ public void post(String url, Map<String, String> params, BaseCallBack callBack, int tag) throws Exception { Request req = buildRequest(url, params, tag); request(req, callBack); } /** * 对外公开的get方法 * * @param url * @param callBack */ public void get(String url, BaseCallBack callBack, int tag) throws Exception { Request req = buildRequest(url, null, tag); request(req, callBack); } /** * 构建request请求对象 * * @param url * @param params * @return */ private Request buildRequest(String url, Map<String, String> params, int tag) { Request.Builder builder = new Request.Builder(); builder.url(url);//请求地址 if (null == params) { builder.get();//get请求 } else { builder.post(buildRequestBody(params));//post请求 添加参数 } builder.tag(tag);//tag 区分不同的请求 return builder.build(); } /** * 通过Map的键值对 构建post请求的RequestBody对象 * * @param params * @return */ private RequestBody buildRequestBody(Map<String, String> params) { FormBody.Builder formEncodingBuilder = new FormBody.Builder(); if (params != null) { for (Map.Entry<String, String> entity : params.entrySet()) { formEncodingBuilder.add(entity.getKey(), entity.getValue()); } } return formEncodingBuilder.build(); } /** * 接口请求 post,get请求通用 * * @param request 请求对象 * @param callBack 回调接口 */ private void request(final Request request, final BaseCallBack callBack) throws Exception { callBack.onRequestBefore(); mClient.newCall(request).enqueue(new Callback() {//异步访问网络 @Override public void onFailure(Call call, final IOException exception) { if (!call.isCanceled()) {//请求未取消 mHandler.post(new Runnable() { @Override public void run() { //请求失败 网络异常 callBack.onFailure(exception); } }); } } @Override public void onResponse(Call call, final Response response) throws IOException { if (!call.isCanceled()) {//链接超时 或者其他原因 导致请求取消 if (response.isSuccessful()) { String res = response.body().string(); mHandler.post(new Runnable() { @Override public void run() { callBack.onSuccess(response, (Integer) response.request().tag()); } }); } else { mHandler.post(new Runnable() { @Override public void run() { //请求成功 获取数据异常 callBack.onError(response, response.code(), null); } }); } } } }); } }
回调接口
public abstract class BaseCallBack<T> { /** * 请求之前调用 */ public abstract void onRequestBefore(); /** * 请求失败(网络问题) * @param e */ public abstract void onFailure(Exception e); /** * 请求成功 * @param response * @param tag */ public abstract void onSuccess(Response response, int tag); /** * 请求成功但是有错误(接口错误,数据解析错误等) * @param response * @param errorCode * @param e */ public abstract void onError(Response response,int errorCode,Exception e); }
补充:
OKHttp 源码:http://blog.csdn.net/u012124438/article/details/54236967
AsyncHttpClient : 基于HTTPClient的异步请求框架 http://www.it165.net/pro/html/201406/16421.html
xutils : http://doc.okbase.net/u010870518/archive/125128.html