Android M(6.x)使用OkHttp包解析和发送JSON请求的教程
关于Android 6.0
Android老版本网络请求:
1,HttpUrlConnection
2,Apache Http Client
Android6.0版本网络请求:
1,HttpUrlConnection
2,OkHttp
Android6.0版本废弃了老的网络请求,那么它的优势是什么呢?
1,支持SPDY,共享同一个Socket来处理同一个服务器的所有请求
2,如果SPDY不可用,则通过连接池来减少请求延时
3,无缝的支持GZIP来减少数据流量
4,缓存响应数据来减少重复的网络请求
post请求发送给服务器JSON:
我们先来看一个样例,详细的请求发送我们下面还会讲.
public class MainActivity extends AppCompatActivity { public static final String TAG = "MainActivity"; public static final MediaType JSON=MediaType.parse("application/json; charset=utf-8"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //开启一个线程,做联网操作 new Thread() { @Override public void run() { postJson(); } }.start(); } private void postJson() { //申明给服务端传递一个json串 //创建一个OkHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient(); //创建一个RequestBody(参数1:数据类型 参数2传递的json串) RequestBody requestBody = RequestBody.create(JSON, json); //创建一个请求对象 Request request = new Request.Builder() .url("http://192.168.0.102:8080/TestProject/JsonServlet") .post(requestBody) .build(); //发送请求获取响应 try { Response response=okHttpClient.newCall(request).execute(); //判断请求是否成功 if(response.isSuccessful()){\ //打印服务端返回结果 Log.i(TAG,response.body().string()); } } catch (IOException e) { e.printStackTrace(); } } }
SPDY(读作“SPeeDY”)是Google开发的基于TCP的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。新协议的功能包括数据流的多路复用、请求优先级以及HTTP报头压缩。谷歌表示,引入SPDY协议后,在实验室测试中页面加载速度比原先快64%。
ZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNⅨ系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。
HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来.一般对纯文本内容可压缩到原大小的40%.这样传输就快了,效果就是你点击网址后会很快的显示出来.当然这也会增加服务器的负载. 一般服务器中都安装有这个功能模块的。
JSON解析
这里我们将采用json统一泛型解析,与一些Java的反射机制来解析泛型对象Class<?>:
1.首先我们声明一个TypeInfo.java类用来封装泛型相关属性
import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class TypeInfo { //Type泛型对象类型 private Class<?> componentType; //Type所属对象类型 private Class<?> rawType; //type private Type type; private TypeInfo(Class<?> rawType, Class<?> componentType) { this.componentType = componentType; this.rawType = rawType; } public static TypeInfo createArrayType(Class<?> componentType) { return new TypeInfo(Array.class, componentType); } public static TypeInfo createNormalType(Class<?> componentType) { return new TypeInfo(null, componentType); } public static TypeInfo createParameterizedType(Class<?> rawType, Class<?> componentType) { return new TypeInfo(rawType, componentType); } public TypeInfo(Type type) { this.type = type; if (type instanceof ParameterizedType) { //返回 Type 对象,表示声明此类型的类或接口。 this.rawType = (Class<?>) ((ParameterizedType) type).getRawType(); //getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。 Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments(); this.componentType = (Class<?>) actualTypeArguments[0]; // typeReference=new TypeReference<Map<componentType,componentType>>(){}; } else if (type instanceof GenericArrayType) { //返回 Type 对象,表示声明此类型的类或接口。 this.rawType = Array.class; // 表示一种元素类型是参数化类型或者类型变量的数组类型 this.componentType = (Class<?>) ((GenericArrayType) type).getGenericComponentType(); } else { this.componentType = (Class<?>) type; } } public Type getType() { return type; } public Class<?> getComponentType() { return componentType; } public Class<?> getRawType() { return rawType; } }
2.声明ReqClassUtils.java类 用于通过反射机制获取泛型对象的TypeInfo
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class ReqClassUtils { public static TypeInfo getCallbackGenericType(Class<?> clazz) { //获得带有泛型的父类 Type genericSuperclass = clazz.getGenericSuperclass();//Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。 TypeInfo type = getGetnericType(genericSuperclass); if (type == null) { Type[] genericInterfaces = clazz.getGenericInterfaces(); if (genericInterfaces != null && genericInterfaces.length > 0) { type = getGetnericType(genericInterfaces[0]); } } return type; } private static TypeInfo getGetnericType(Type type) { if (type != null && type instanceof ParameterizedType) { //getActualTypeArguments获取参数化类型的数组,泛型可能有多个 Type[] args = ((ParameterizedType) type).getActualTypeArguments(); if (args != null && args.length > 0) { return new TypeInfo(args[0]); } } return null; } }
3.接下来重点来了,声明一个json解析工具类ReqJsonUtils.java,主要用于通过TypeInfo相关属性进行不同类型的json解析