说起访问网络,很天然的会用到okHttp,虽然okhttp已经封装的比较完善, 调用也比较方便,但对于向我这样比较懒的人,okhttp的调用仍是略显复杂, 每次都要写一样重复的代码,简直不能忍受,那就封装如下一句话调用完毕,岂不快哉。。。 废话很少说,请抓稳扶好,老司机,走起。。。
重要的事情提一提:看不懂的文章最后有完整代码,看看完整版应该就没问题了。java
没有什么是一张图说不清的,走起
网络访问框架通常都须要单例模式(singleton),首先咱们也进行单利模式。 1 首先私有化构造器,让别人不能new出其它实例。 2 声明该类的一个静态成员变量实例,本篇为instance 3 声明一个公有的方法getInstance提供给调用者本类实例。 /** * 网络访问要求singleton */ private static OkHttpUtils instance; // 必需要用的okhttpclient实例,在构造器中实例化保证单一实例 private OkHttpClient mOkHttpClient; private OkHttpUtils() { /** * okHttp3中超时方法移植到Builder中 */ mOkHttpClient = (new OkHttpClient()).newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); } public static OkHttpUtils getInstance() { if (instance == null) { synchronized (OkHttpUtils.class) { if (instance == null) { instance = new OkHttpUtils(); } } } return instance; } 上面代码在构造器中实例化出了okHttpClient的实例,既然咱们这个帮助类是单例的,那么构造器中的okHttpClient也只会走一次,一定也是单实例的。
既然是工具类,确定要更加简单,此处咱们须要提供针对GET和POST两种方式的访问方法。
/** * 对外提供的Get方法访问 * @param url * @param callBack */ public void Get(String url, MyCallBack callBack) { /** * 经过url和GET方式构建Request */ Request request = bulidRequestForGet(url); /** * 请求网络的逻辑 */ requestNetWork(request, callBack); }
/** * 对外提供的Post方法访问 * @param url * @param parms: 提交内容为表单数据 * @param callBack */ public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) { /** * 经过url和POST方式构建Request */ Request request = bulidRequestForPostByForm(url, parms); /** * 请求网络的逻辑 */ requestNetWork(request, callBack); }
/** * 对外提供的Post方法访问 * @param url * @param json: 提交内容为json数据 * @param callBack */ public void PostWithJson(String url, String json, MyCallBack callBack) { /** * 经过url和POST方式构建Request */ Request request = bulidRequestForPostByJson(url, json); /** * 请求网络的逻辑 */ requestNetWork(request, callBack); }
从这两个方法,咱们能看到咱们须要构建GET和POST访问方式对应的Request对象和咱们自定义的MycallBack接口,下面先来看一下构建Request对象。json
为了你们更好的理解封装流程,首先请你们回顾一下okhttp的使用流程: mOkHttpClient.newCall(request).enqueue(new Callback() {})
1.首先咱们来看构建GET须要的Request对象,这个也是最简单的。markdown
/** * GET方式构建Request * @param url * @return */ private Request bulidRequestForGet(String url) { return new Request.Builder() .url(url) .get() .build(); }
2.构建提交表单数据的Request对象网络
/** * POST方式构建Request {Form} * @param url * @param parms * @return */ private Request bulidRequestForPostByForm(String url, Map<String, String> parms) { FormBody.Builder builder = new FormBody.Builder(); if (parms != null) { for (Map.Entry<String, String> entry : parms.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } } FormBody body = builder.build(); return new Request.Builder() .url(url) .post(body) .build(); }
3.构建提交json数据的Request对象app
/** * POST方式构建Request {json} * @param url * @param json * @return */ private Request bulidRequestForPostByJson(String url, String json) { RequestBody body = RequestBody.create(JSON, json); return new Request.Builder() .url(url) .post(body) .build(); }
上述代码及分析基本上把简单封装的东西讲完了,有了okhttpclient和request对象咱们须要处理联网逻辑了,也就是上述的 requestNetWork方法。 private void requestNetWork(Request request, MyCallBack callBack) { /** * 处理连网逻辑,此处只处理异步操做enqueue */ callBack.onLoadingBefore(request); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { callBack.onFailure(request, e); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { callBack.onSuccess(response); } else { callBack.onError(response); } } }); }
看到此处,估计有人会一脸懵逼,这个MyCallBack是个什么鬼。 其实这是我定义的一个接口,那么为何要定义她呢。由于咱们在使用咱们的工具类的时候,访问网络成功后确定会有数据返回,咱们怎么处理呢,okhttp内部经过一个callBack把数据回调回来,那么咱们本身封装的工具类不妨仿照他的作法 定义一个接口回调Response的内容。贴一下接口的内容 interface MyCallBack { void onLoadingBefore(Request request); void onSuccess(Response response); void onFailure(Request request, Exception e); void onError(Response response);
}框架
看到此处,以为封装已经完结了,不不不,还有一个重要的问题,不处理的话会致使崩溃的,这个问题就是,咱们定义接口回调的地方是在子线程,而咱们的Response很明显须要拿回到主线程进行UI的更新,因此访问网络的方法requestNetWork须要经过Handler把子线程的Resonse发送到主线程,请看详细实现。
private void requestNetWork(Request request, MyCallBack callBack) {异步
/** * 处理连网逻辑,此处只处理异步操做enqueue */ callBack.onLoadingBefore(request); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { mHandler.post(() -> callBack.onFailure(request, e)); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { mHandler.post(() -> callBack.onSuccess(response)); } else { mHandler.post(() -> callBack.onError(response)); } } }); }
此工具类尚未完善,下篇文章继续完善,待完善内容:返回Resonpse直接解析成javaBean返回。
public class OkHttpUtils { /** * 网络访问要求singleton */ private static OkHttpUtils instance; // 必需要用的okhttpclient实例,在构造器中实例化保证单一实例 private OkHttpClient mOkHttpClient; public static final MediaType JSON = MediaType. parse("application/json; charset=utf-8"); private Handler mHandler; private OkHttpUtils() { /** * okHttp3中超时方法移植到Builder中 */ mOkHttpClient = (new OkHttpClient()).newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); mHandler = new Handler(Looper.getMainLooper()); } public static OkHttpUtils getInstance() { if (instance == null) { synchronized (OkHttpUtils.class) { if (instance == null) { instance = new OkHttpUtils(); } } } return instance; } /** * 对外提供的Get方法访问 * @param url * @param callBack */ public void Get(String url, MyCallBack callBack) { /** * 经过url和GET方式构建Request */ Request request = bulidRequestForGet(url); /** * 请求网络的逻辑 */ requestNetWork(request, callBack); } /** * 对外提供的Post方法访问 * @param url * @param parms: 提交内容为表单数据 * @param callBack */ public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) { /** * 经过url和POST方式构建Request */ Request request = bulidRequestForPostByForm(url, parms); /** * 请求网络的逻辑 */ requestNetWork(request, callBack); } /** * 对外提供的Post方法访问 * @param url * @param json: 提交内容为json数据 * @param callBack */ public void PostWithJson(String url, String json, MyCallBack callBack) { /** * 经过url和POST方式构建Request */ Request request = bulidRequestForPostByJson(url, json); /** * 请求网络的逻辑 */ requestNetWork(request, callBack); } /** * POST方式构建Request {json} * @param url * @param json * @return */ private Request bulidRequestForPostByJson(String url, String json) { RequestBody body = RequestBody.create(JSON, json); return new Request.Builder() .url(url) .post(body) .build(); } /** * POST方式构建Request {Form} * @param url * @param parms * @return */ private Request bulidRequestForPostByForm(String url, Map<String, String> parms) { FormBody.Builder builder = new FormBody.Builder(); if (parms != null) { for (Map.Entry<String, String> entry : parms.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } } FormBody body = builder.build(); return new Request.Builder() .url(url) .post(body) .build(); } /** * GET方式构建Request * @param url * @return */ private Request bulidRequestForGet(String url) { return new Request.Builder() .url(url) .get() .build(); } private void requestNetWork(Request request, MyCallBack callBack) { /** * 处理连网逻辑,此处只处理异步操做enqueue */ callBack.onLoadingBefore(request); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { mHandler.post(() -> callBack.onFailure(request, e)); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { mHandler.post(() -> callBack.onSuccess(response)); } else { mHandler.post(() -> callBack.onError(response)); } } }); } }
定义的接口的完整代码ide
interface MyCallBack {
void onLoadingBefore(Request request); void onSuccess(Response response); void onFailure(Request request, Exception e); void onError(Response response); }