嗨,大家好。又和大家见面了,今天我和大家一起来学习一下OKHttp。
OKHttp是基于Http协议上的网络通讯,说白了就是Http协议。Http的功能OKHttp都有。那就问题来了,既然有了Http,这 强大的协议,为什么还需要有OKHttp等将Http封装的架包呢?其实编程是一个工作量大,工作重复性普遍的工作。编程人员都不喜欢做重复性的工作和处理Bug。个人感觉OKHttp就是基于这一系列的因素。所以OKHttp就诞生了。
OkHttp由于基于Http协议,所以http协议都支持。例如请求报文,响应报文,所有的请求方法等多做了很好的的处理。所以有关Http的知识就不详细讲解了,读者可以自己去查询资料了解一下。下面介绍使用OkHttp访问网络。
其实使用OKHttp访问网络很简单,主要通过以下几步:
1、初始化OKHttpClient实例
注:OKHttpClient在整个项目中使用单例模式,尽量直接new实例
//初始化OkHttpClient,OkHttpClient将采用单例模式 private static OkHttpClient okHttpClient = new OkHttpClient();2、初始化RequestBody实例,用于封装请求的内容(PS:如果使用get请求可以直接省略该步骤)
//初始化RequestBody,用于保存我访问网络的请求信息 RequestBody requestBody = RequestBody.create(JSONTYPE, requestContent);
3、初始化Request实例,用于封装请求信息
Request request = builder.url(url).build();
4、初始化Call实例,用于访问网络
//初始化Call对象,用于访问网络 Call call = okHttpClient.newCall(request);
5、访问网络,OKhttp访问网络提供了两种方法
5.1、同步方法,返回Response对象,该对象封装了网络资源信息
//初始化Response对象,用于显示访问网络的响应头信息 Response response = call.execute();
5.2、异步方法 (PS:异步方法采用Callback接口回调机制)
/* * 采用异步方法访问网络,返回响应报文信息 * */ public void enqueue(String url, Callback callback, String requestContent) { if (requestContent == null || "".equals(requestContent)) { //采用异步get方法访问网络 Request request = this.getRequest(url); //初始化Call对象,用于网络连接 Call call = okHttpClient.newCall(request); //采用异步访问网络 call.enqueue(callback); } else { //采用异步post方法访问网络 Request request = this.getRequest(url, requestContent); //初始化Call对象,用于网络连接 Call call = okHttpClient.newCall(request); call.enqueue(callback); } }
6、通过Response获得网络资源
//初始化ResponseBody对象,用于封装网络资源,该实体用许多访问网络资源的方法 ResponseBody body = response.body(); //以字符串的形式获得网络 result = body.string(); //以字符流的形式获得网络 //body.charStream(); //以字节的形式获得网络 // body.bytes(); //以字节流的形式获得网络 //body.byteStream();
//获得响应头 Headers headers = response.headers(); //遍历响应头信息 for (int i = 0; i < headers.size(); i++){ Log.d("tag",headers.name(i) + "--->" + headers.value(i)); }
通过以上的步骤就可以访问网络了,很简单嘛。但别以为OKHttp就只有这点功能,我这里仅仅简单介绍一下,帮助大家引进门,最好的学习方法就是看APi,看源码学习,了解大神的编程思想。
下面我将我学习OKHttp过程编写的工具类copy出来,提供大家学习。
/* * * 该工具类采用单例模式 * */ public class OkHttpUtils { //初始化OkHttpClient,OkHttpClient将采用单例模式 private static OkHttpClient okHttpClient = new OkHttpClient(); //初始化OkHttpUtils private static OkHttpUtils okHttpUtils = new OkHttpUtils(); //发送请求消息为Json类型 private static final MediaType JSONTYPE = MediaType.parse("application/*; charset=utf-8"); //构造私有的构造器,使外部不能直接创建实例 private OkHttpUtils() { } //采用单例模式中饿汉模式 public static OkHttpUtils getInstance() { return okHttpUtils; } //采用类方法获得单一的OkHttpClient实例 public static OkHttpClient getOkHttpClient() { return okHttpClient; } /* * 获得get方法Request的请求信息 * */ private Request getRequest(String url) { return getRequest(url, null); } /* * 获取响应头 * */ public void getHeader(String url) { getHeader(url, null); } /* * 获取响应头 * */ public void getHeader(String url, String requestContent) { //初始化Request对象用于封装请求消息 Request request = this.getRequest(url, requestContent); try { //访问网络,获得响应信息 Response response = this.execute(request); //获得响应头 Headers headers = response.headers(); //遍历响应头信息 for (int i = 0; i < headers.size(); i++){ Log.d("tag",headers.name(i) + "--->" + headers.value(i)); } } catch (IOException e) { e.printStackTrace(); } } /* * call.execute()访问网络,返回响应报文信息 * */ private Response execute(Request request) throws IOException { //初始化Call对象,用于访问网络 Call call = okHttpClient.newCall(request); //初始化Response对象,用于显示访问网络的响应头信息 Response response = call.execute(); return response; } /* * 采用异步方法访问网络,返回响应报文信息 * */ public void enqueue(String url, Callback callback) { enqueue(url, callback, null); } /* * 采用异步方法访问网络,返回响应报文信息 * */ public void enqueue(String url, Callback callback, String requestContent) { if (requestContent == null || "".equals(requestContent)) { //采用异步get方法访问网络 Request request = this.getRequest(url); //初始化Call对象,用于网络连接 Call call = okHttpClient.newCall(request); //采用异步访问网络 call.enqueue(callback); } else { //采用异步post方法访问网络 Request request = this.getRequest(url, requestContent); //初始化Call对象,用于网络连接 Call call = okHttpClient.newCall(request); call.enqueue(callback); } } /* * 获得post方法的Request请求信息,当requestContent信息为null时,默认为get请求 * */ private Request getRequest(String url, String requestContent) { if ("".equals(requestContent) || requestContent == null) { //定义Rquest对象,封装访问网络的请求信息 //new Request.Builder()创建Request的内部类Builder的对象,默认通过get方法访问网络 Request.Builder builder = new Request.Builder(); //关联访问网络的url,并将其转换为Request对象 Request request = builder.url(url).build(); return request; } else { //初始化RequestBody,用于保存我访问网络的请求信息 RequestBody requestBody = RequestBody.create(JSONTYPE, requestContent); //初始化Request,用于封装请求报头 Request request = new Request.Builder().url(url).post(requestBody).build(); return request; } } //OkHttpClient的get方法 public Object get(String url) throws IOException { Object result = null; //关联访问网络的url,并将其转换为Request对象 Request request = this.getRequest(url); Response response = this.execute(request); //检测网络是否连接成功 if (response.isSuccessful()) { //获取网连接信息 String mess = response.message(); Log.d("tag", "mess = " + mess); //初始化ResponseBody对象,用于封装网络资源,该实体用许多访问网络资源的方法 ResponseBody body = response.body(); //以字符串的形式获得网络 result = body.string(); //以字符流的形式获得网络 //body.charStream(); //以字节的形式获得网络 // body.bytes(); //以字节流的形式获得网络 //body.byteStream(); } else { //如果没有连接成功则抛出io异常,答应出错误码 throw new IOException("Unexcepted code = " + response.code()); } return result; } //OkHttpClient的get方法 public Object post(String url, String requestContent) throws IOException { String result = null; //初始化Request,用于封装请求报头 Request request = this.getRequest(url, requestContent); //访问网络,返回相应报文 Response response = this.execute(request); //检测网络是否连接成功 if (response.isSuccessful()) { //获取网连接信息 String mess = response.message(); Log.d("tag", "mess = " + mess); //初始化ResponseBody对象,用于封装网络资源,该实体用许多访问网络资源的方法 ResponseBody body = response.body(); //以字符串的形式获得网络 result = body.string(); //以字符流的形式获得网络 //body.charStream(); //以字节的形式获得网络 // body.bytes(); //以字节流的形式获得网络 //body.byteStream(); } else { //如果没有连接成功则抛出io异常,答应出错误码 throw new IOException("Unexcepted code = " + response.code()); } return result; } }
PS: 以上代码可以Copy在项目中直接运行
最后感谢大家的阅读,由于本人是菜鸟,知识有限,有错误的地方欢迎大家提出。