Okhttp3网络请求框架简析思考——Android网络请求框架(五)
2016-09-13 00:00
666 查看
摘要: 1、单例设计模式封装工具类
2、对网络请求设置缓存
3、对网络请求设置超时间
4、get请求
5、Post请求
6、post提交表单数据请求
7、post提交JSON数据请求
站在世界的巅峰看世界的心情,决不是一个普通人能够体会的到的感觉
分析 简述:
1-1、可以看到上面三种创建单例的方法,第一种方式被传统命名为饿汉式,单例对象随着类的加载而被创建,当我们使用类中的其他静态方法而没有使用到单例对象的时候,单例对象依然会被创建出来,从某种角度来说,造成了一定的内存浪费。
1-2、第二种方式被传统命名为懒汉式,也就是在调用实例化对象的时候,才会将单例对象创建出来,当我们使用类中的其他静态方法的时候,会同时有单例对象的null引用生成,在一定程度上会很消耗内存,再者创建实例化对象的时候,双重非空锁判断,也是相当消耗性能的工作。
1-3、第三种方式可以称为是完美设计版了,因为它可以解决前两种设计方法的不足之处,当去调用类的实例化方法的时候,单例对象才会被创建,而当调用类中的其他静态方法的时候,对静态单例对象没有任何的操作,所以可以说是比较完美的了,之所以可以称为比较而不是完全,是因使用这种方式创建,在进行序列化与反序列化的时候,会出现非单例对象问题。
当然在使用Okhttp3的时候 要先关联依赖
4-1 创建请求Request对象
4-2创建封装参数的RequestBody对象(GET方法除外)
4-3 封装请求参数
4-4 创建请求Response对象实例
4-5 发起网络请求
4-6 处理回调监听
4-7 处理取消网络请求标签
这是GET请求参数最多的方法,我们可以在此基础上封装少参数的方法,例如不需要设置请求头,请求参数,不指定缓存模式,对应的传入null就可以。这里实际上就是将传入的参数以KEY - VALUE的方式拼接在了请求链接中
对于网络请求模式,默认有两种,一是强制使用网络请求数据 ,一是强制使用缓存,一般使用默认使用网络请求就可以
使用案例 :
通过抓包可以看到我们提交的请求数据为
案例:
通过抓包工具可以看到提交的数据为:
提交数据的格式为: Content - Type:application/x-www-form-urlencoded
添加的请求头为 verson : 11
提交的参数为:
在这里,我们将参数以map集合形式传入,然后封装成JSONObject对象,然后在构造请求体,
例 :
通过抓包工具可以看到提交的请求数据为:
请求方式为:
在这里,我们将直接构造好的JSON 字符串直接传入到方法中,然后构造请求体
案例:
提交的请求数据为:
也就是说在这里我们可以定义任意结构层次的JSON数据
案例:
提交的数据格式 :
提交的数据原型:
10、POST源码简述:
2、对网络请求设置缓存
3、对网络请求设置超时间
4、get请求
5、Post请求
6、post提交表单数据请求
7、post提交JSON数据请求
站在世界的巅峰看世界的心情,决不是一个普通人能够体会的到的感觉
1、对单例设计模式的思考
创建方式一 、
/** * Created by androidlongs on 16/9/12. * 站在顶峰,看世界 * 落在谷底,思人生 */ /** * 创建方式一: * * 当在JVM在加载单例类的时候,单例对象就会被建立 * 当其中有其他的静态方法的时候,使用类调用方法,没有使用到该单例对象,但是单例对象也会被创建出来,从而造成了资源的浪费 */ public class Singleton { //直接创建 public static Singleton sSingleton = new Singleton(); //私有构造函数 private Singleton(){ } //返回对象体 public static Singleton getInstance(){ return sSingleton; } //获取String的方法 public static String getString(){ return "single"; } }
创建方式 二
/** * Created by androidlongs on 16/9/12. * 站在顶峰,看世界 * 落在谷底,思人生 */ /** * 创建方式二 * * 有点性能上的损失 */ class SingletonLazy{ //声明变量 public static SingletonLazy sSingletonLazy; //私有构造函数 private SingletonLazy(){ } //提供对外方法 public static SingletonLazy getInstance(){ if (sSingletonLazy == null) { synchronized (SingletonLazy.class){ if (sSingletonLazy == null) { sSingletonLazy = new SingletonLazy(); } } } return sSingletonLazy; } //获取String的方法 public static String getString(){ return "single"; } }
创建方式三:
/** * 创建方式三 */ class CommonSingleton{ //私有构造 private CommonSingleton(){ } //提供对外方法 public static CommonSingleton getInstance(){ return SingletonHolder.commonSingleton; } //内部类方法维护 private static class SingletonHolder{ private static CommonSingleton commonSingleton = new CommonSingleton(); } //获取String的方法 public static String getString(){ return "single"; } }
分析 简述:
1-1、可以看到上面三种创建单例的方法,第一种方式被传统命名为饿汉式,单例对象随着类的加载而被创建,当我们使用类中的其他静态方法而没有使用到单例对象的时候,单例对象依然会被创建出来,从某种角度来说,造成了一定的内存浪费。
1-2、第二种方式被传统命名为懒汉式,也就是在调用实例化对象的时候,才会将单例对象创建出来,当我们使用类中的其他静态方法的时候,会同时有单例对象的null引用生成,在一定程度上会很消耗内存,再者创建实例化对象的时候,双重非空锁判断,也是相当消耗性能的工作。
1-3、第三种方式可以称为是完美设计版了,因为它可以解决前两种设计方法的不足之处,当去调用类的实例化方法的时候,单例对象才会被创建,而当调用类中的其他静态方法的时候,对静态单例对象没有任何的操作,所以可以说是比较完美的了,之所以可以称为比较而不是完全,是因使用这种方式创建,在进行序列化与反序列化的时候,会出现非单例对象问题。
2、使用单例设计模式来创建Okhttp网络请求框架
/** * Created by androidlongs on 16/9/12. * 站在顶峰,看世界 * 落在谷底,思人生 */ public class CommonOkhttpUtils { //私有化构造 private CommonOkhttpUtils(){ //初始化Okhttp配制 initOkHttpFunction(); } //提供实例化对象 public static CommonOkhttpUtils getUtilsInstance(){ return OkHttpSingle.sCommonOkhttpUtils; } //实例静态内部类 private static class OkHttpSingle{ private static CommonOkhttpUtils sCommonOkhttpUtils = new CommonOkhttpUtils(); } //初始化Okhttp配制 private void initOkHttpFunction() { } }
当然在使用Okhttp3的时候 要先关联依赖
compile 'com.squareup.okhttp3:okhttp:3.3.1'
3、对Okhttp3进行的一些初始化配制
private OkHttpClient mOkHttpClient; //初始化Okhttp配制 private void initOkHttpFunction() { //配制网络数据缓存 File cacheDirectory = APPApplication.getmContext().getExternalCacheDir(); //配制网络数据缓存大小 10M int cacheSize = 10*1024*1024; // Cache cache = new Cache(cacheDirectory,cacheSize); //创建HttpClientBuilder OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); //设置缓存 以及超时间 以及获取OkHttpClient对象 mOkHttpClient = builder.writeTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .cache(cache) .build(); }
4、网络请求思路综述
其实创建一个网络连接并没有多复杂4-1 创建请求Request对象
4-2创建封装参数的RequestBody对象(GET方法除外)
4-3 封装请求参数
4-4 创建请求Response对象实例
4-5 发起网络请求
4-6 处理回调监听
4-7 处理取消网络请求标签
5、GET异步请求(可传参数 )
/** * 异步GET网络请求 * * @param url 请求网络链接 * @param headerMap 请求网络添加头信息 * @param paramsMap 请求网络参数 * @param cacheControl 缓存模式 * * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 响应回调 * @param tag 网络任务标识 */ public void okHttpGetRequest(String url, Map<String, String> headerMap, Map<String, String> paramsMap, CacheControl cacheControl, Callback callback, String tag) { //GET请求-1 封装请求参数 //Get请求传参数实际上是在请求链接中携带参数 StringBuilder sb = new StringBuilder(); sb.append(url).append("?"); if (paramsMap != null && !paramsMap.isEmpty()) { for (String key : paramsMap.keySet()) { sb.append(key).append("=").append(paramsMap.get(key)).append("&"); } sb = sb.deleteCharAt(sb.length() - 1); url = sb.toString(); } //GET请求-2 获取Builder Request.Builder builder = new Request.Builder().url(url); //GET请求-3 设置缓存 if (cacheControl != null) { builder.cacheControl(cacheControl); } //GET请求-4添加请求头信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { builder.addHeader(entry.getKey(), entry.getValue()); } } //GET请求-5 创建请求Request对象 Request request = builder.build(); //GET请求-6 设置取消标签 Call call = mOkHttpClient.newCall(request); //将请求标签添加到请求Key集合中 mCallHashMap.put(tag, call); //GET请求-5 发起网络请求 call.enqueue(callback); } /** * 移除 取消网络任务 * * @param tag */ public void removeRequest(String tag) { //获取KEY的集合 Set<Map.Entry<String, Call>> keyEntries = mCallHashMap.entrySet(); //如果包含KEY if (keyEntries.contains(tag)) { //获取对应的Call Call call = mCallHashMap.get(tag); //如果没有被取消 执行取消的方法 if (!call.isCanceled()) { call.cancel(); } //移除对应的KEY mCallHashMap.remove(tag); } }
这是GET请求参数最多的方法,我们可以在此基础上封装少参数的方法,例如不需要设置请求头,请求参数,不指定缓存模式,对应的传入null就可以。这里实际上就是将传入的参数以KEY - VALUE的方式拼接在了请求链接中
对于网络请求模式,默认有两种,一是强制使用网络请求数据 ,一是强制使用缓存,一般使用默认使用网络请求就可以
使用案例 :
//GET访问 private void getRequestFunction() { //请求链接 String url = ""; //网络请求标识 String tag = "getRequest"; //提交参数 Map<String, String> paramMap = new HashMap<>(); paramMap.put("userName", "xxx"); paramMap.put("password", "123456"); //添加请求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okHttpGetRequest(url, heardMap, paramMap, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //请求失败回调方法 } @Override public void onResponse(Call call, Response response) throws IOException { //请求成功回调方法 } }, tag); } //取消网络请求 private void canlaneRequest(String tag){ CommonOkhttpUtils.getUtilsInstance().removeRequest(tag); }
通过抓包可以看到我们提交的请求数据为
6、POST异步请求提交表单数据
/** * 异步POST网络请求 提交表单数据 * * @param url 请求网络链接 * @param headerMap 请求网络添加头信息 * @param parmMap 请求网络参数 * @param cacheControl 缓存模式 * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 响应回调 * @param tag 网络任务标识 */ public void okPostFormRequest(String url, Map<String, String> headerMap, Map<String, String> parmMap, CacheControl cacheControl, Callback callback, String tag) { //POST - FORM 表单 获取请求参数BODY FormBody.Builder formBuilder = new FormBody.Builder(); //POST - FORM 表单 封装参数 if (parmMap != null && !parmMap.isEmpty()) { for (Map.Entry<String, String> entry : parmMap.entrySet()) { formBuilder.add(entry.getKey(), entry.getValue()); } } //POST - FORM 获取表单BODY RequestBody formBody = formBuilder.build(); //POST - FORM 构建请求Request Builder Request.Builder requestBuilder = new Request.Builder().url(url); //POST - FORM 设置缓存 if (cacheControl != null) { requestBuilder.cacheControl(cacheControl); } //POST - FORM 添加请求头信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { requestBuilder.addHeader(entry.getKey(), entry.getValue()); } } //POST - FORM 构建请求Request Request request = requestBuilder.post(formBody).build(); //POST - FORM 构建请求响应Call Call call = mOkHttpClient.newCall(request); //POST - FORM 设置取消任务标签 mCallHashMap.put(tag,call); //POST - FORM 发起请求 call.enqueue(callback); } /** * 移除 取消网络任务 * * @param tag */ public void removeRequest(String tag) { //获取KEY的集合 Set<Map.Entry<String, Call>> keyEntries = mCallHashMap.entrySet(); //如果包含KEY if (keyEntries.contains(tag)) { //获取对应的Call Call call = mCallHashMap.get(tag); //如果没有被取消 执行取消的方法 if (!call.isCanceled()) { call.cancel(); } //移除对应的KEY mCallHashMap.remove(tag); } } }
案例:
private void postRequestForm() { //请求链接 String url = "http://192.168.1.107:8080/OkhttpAppLication/test"; //网络请求标识 String tag = "getRequest"; //提交参数 Map<String, String> paramMap = new HashMap<>(); paramMap.put("userName", "xxx"); paramMap.put("password", "123456"); //添加请求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okPostFormRequest(url, heardMap, paramMap, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //请求失败回调方法 } @Override public void onResponse(Call call, Response response) throws IOException { //请求成功回调方法 } }, tag); }
通过抓包工具可以看到提交的数据为:
提交数据的格式为: Content - Type:application/x-www-form-urlencoded
添加的请求头为 verson : 11
提交的参数为:
7、POST异步请求提交JSON数据
/** * 异步POST网络请求 提交JSON数据 * * @param url 请求网络链接 * @param headerMap 请求网络添加头信息 * @param parmMap 请求网络参数 * @param cacheControl 缓存模式 * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 响应回调 * @param tag 网络任务标识 */ public void okPostJSONRequest(String url, Map<String, String> headerMap, Map<String, String> parmMap, CacheControl cacheControl, Callback callback, String tag) { //获取Builder Request.Builder builder = new Request.Builder().url(url); // 设置缓存 if (cacheControl != null) { builder.cacheControl(cacheControl); } //添加请求头信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { builder.addHeader(entry.getKey(), entry.getValue()); } } /** * 封装参数 */ JSONObject jsonObject = new JSONObject(); if (parmMap != null && !parmMap.isEmpty()) { for (Map.Entry<String, String> entry :parmMap.entrySet()) { try { jsonObject.put(entry.getKey(), entry.getValue()); } catch (JSONException e) { e.printStackTrace(); } } } //获取RequestBody RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),jsonObject.toString()); //获取 Request Request request = builder.post(requestBody).build(); //获取Call Call call = mOkHttpClient.newCall(request); //POST - JSON 设置取消任务标签 mCallHashMap.put(tag,call); //POST - JSON 发起请求 call.enqueue(callback); } /** * 移除 取消网络任务 * * @param tag */ public void removeRequest(String tag) { //获取KEY的集合 Set<Map.Entry<String, Call>> keyEntries = mCallHashMap.entrySet(); //如果包含KEY if (keyEntries.contains(tag)) { //获取对应的Call Call call = mCallHashMap.get(tag); //如果没有被取消 执行取消的方法 if (!call.isCanceled()) { call.cancel(); } //移除对应的KEY mCallHashMap.remove(tag); } }
在这里,我们将参数以map集合形式传入,然后封装成JSONObject对象,然后在构造请求体,
例 :
private void postJsonFunction() { //请求链接 String url = "http://192.168.1.107:8080/OkhttpAppLication/test"; //网络请求标识 String tag = "getRequest"; //提交参数 Map<String, String> paramMap = new HashMap<>(); paramMap.put("userName", "xxx"); paramMap.put("password", "123456"); paramMap.put("sex", "man"); //添加请求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okPostJSONRequest(url, heardMap, paramMap, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //请求失败回调方法 } @Override public void onResponse(Call call, Response response) throws IOException { //请求成功回调方法 } }, tag); }
通过抓包工具可以看到提交的请求数据为:
请求方式为:
8、POST异步请求提交JSON数据
/** * 异步POST网络请求 提交JSON数据 * * @param url 请求网络链接 * @param headerMap 请求网络添加头信息 * @param JSONBody 请求网络JSON字符串 * @param cacheControl 缓存模式 * * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 响应回调 * @param tag 网络任务标识 */ public void okPostJSONRequest(String url, Map<String, String> headerMap, String JSONBody, CacheControl cacheControl, Callback callback, String tag) { //获取Builder Request.Builder builder = new Request.Builder().url(url); // 设置缓存 if (cacheControl != null) { builder.cacheControl(cacheControl); } //添加请求头信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { builder.addHeader(entry.getKey(), entry.getValue()); } } //获取RequestBody RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSONBody); //获取 Request Request request = builder.post(requestBody).build(); //获取Call Call call = mOkHttpClient.newCall(request); //POST - JSON 设置取消任务标签 mCallHashMap.put(tag, call); //POST - JSON 发起请求 call.enqueue(callback); }
在这里,我们将直接构造好的JSON 字符串直接传入到方法中,然后构造请求体
案例:
private void postJsonFunction1() { //请求链接 String url = "http://192.168.1.107:8080/OkhttpAppLication/test"; //网络请求标识 String tag = "getRequest"; //提交参数 String JSONString = ""; JSONObject jsonObj = new JSONObject(); JSONArray jsonArray = new JSONArray(); try { for (int i = 0; i < 4; i++) { JSONObject jsono = new JSONObject(); jsono.put("userName", "xxx" + i); jsono.put("password", "123456" + i); jsonArray.put(jsono); } jsonObj.put("date", jsonArray); jsonObj.put("sex", "man"); }catch (Exception e){ } JSONString = jsonObj.toString(); //添加请求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okPostJSONRequest(url, heardMap,JSONString, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //请求失败回调方法 } @Override public void onResponse(Call call, Response response) throws IOException { //请求成功回调方法 } }, tag); }
提交的请求数据为:
{ "date": [{ "userName": "xxx0", "password": "1234560" }, { "userName": "xxx1", "password": "1234561" }, { "userName": "xxx2", "password": "1234562" }, { "userName": "xxx3", "password": "1234563" }], "sex": "man" }
也就是说在这里我们可以定义任意结构层次的JSON数据
9、POST异步请求提交String 数据
/** * 异步POST网络请求 提交String数据 * * @param url 请求网络链接 * @param headerMap 请求网络添加头信息 * @param string 请求网络JSON字符串 * @param cacheControl 缓存模式 * * public static final CacheControl FORCE_NETWORK = ..; * * public static final CacheControl FORCE_CACHE = ... * @param callback 响应回调 * @param tag 网络任务标识 */ public void okPostStringRequest(String url, Map<String, String> headerMap, String string, CacheControl cacheControl, Callback callback, String tag) { //获取Builder Request.Builder builder = new Request.Builder().url(url); // 设置缓存 if (cacheControl != null) { builder.cacheControl(cacheControl); } //添加请求头信息 if (headerMap != null && !headerMap.isEmpty()) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { builder.addHeader(entry.getKey(), entry.getValue()); } } //获取RequestBody RequestBody requestBody = RequestBody.create(MediaType.parse("text/x-markdown; charset=utf-8"), string); //获取 Request Request request = builder.post(requestBody).build(); //获取Call Call call = mOkHttpClient.newCall(request); //POST - JSON 设置取消任务标签 mCallHashMap.put(tag, call); //POST - JSON 发起请求 call.enqueue(callback); }
案例:
private void postStringFunction() { //请求链接 String url = "http://192.168.1.107:8080/OkhttpAppLication/test"; //网络请求标识 String tag = "getRequest"; //提交参数 String str = "this is String request data"; //添加请求Header Map<String, String> heardMap = new HashMap<>(); heardMap.put("verson", "11"); CommonOkhttpUtils.getUtilsInstance().okPostStringRequest(url, heardMap, str, CacheControl.FORCE_NETWORK, new Callback() { @Override public void onFailure(Call call, IOException e) { //请求失败回调方法 } @Override public void onResponse(Call call, Response response) throws IOException { //请求成功回调方法 } }, tag); }
提交的数据格式 :
提交的数据原型:
10、POST源码简述:
相关文章推荐
- Okhttp网络请求框架简析——Android网络请求框架(一)
- Okhttp使用简析——Android网络请求框架(一)
- Android网络请求框架剖析一、Okhttp
- Volley网络请求框架简析——Android网络请求框架(三)
- 使用okhttp androidannotaion springandroid 等框架搭建请求网络的框架
- 在android中使用OkHttp框架处理网络请求
- android网络框架OkHttp之get请求(源码初识)
- 简析Android网络请求Volley框架的工作原理
- Android网络请求框架的使用okhttp
- OkHttp3-Android网络请求框架常用用法介绍与实例(mob请求天气预报)
- Android网络请求框架----Okhttp3完全解析(1),使用篇
- Android ——网络请求框架OkHttp使用
- Retrofit 2.0使用详解,配合OkHttp、Gson,Android最强网络请求框架
- Retrofit网络请求框架使用简析——Android网络请求框架(四)
- Android网络请求框架----okHttp3
- android网络框架OkHttp之get请求(源码初识)
- NoHttp使用简析——Android网络请求框架(二)
- Volley网络请求框架简析——Android网络请求框架(三)
- Android网络请求框架----Okhttp3完全解析(2),封装框架
- android网络请求框架的学习之路——浅谈对Volley,OkHttp,Retrofit的了解与对比 标签: androidVolleyOkhttpRetrofit网络请求框架