okhttp框架的使用
来源:互联网 发布:同济大学图书馆知乎 编辑:程序博客网 时间:2024/05/17 02:59
okHttp框架
OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,
通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势
jar包依赖
需要添加两个jar包okhttp和对应版本的okio
本文使用okhttp3.3 okio1.6
GET 方式
建立连接
Request对象用于建立连接
// 首先得有一个OkHttpClient对象OkHttpClient mOkClient = new OkHttpClient();// 创建请求对象Request request = new Builder().url(URL_STR).build();
接收请求
Reponse对象用于接收响应
Response response = mOkClient.newCall(request).execute();
以同步的方式接收请求,会产生阻塞
public class Main { private static OkHttpClient mOkClient = new OkHttpClient(); private final static String URL_STR = "https://www.baidu.com"; public static void main(String[] args) { // 创建请求对象 Request request = new Builder().url(URL_STR).build(); try { // 创建回调并执行响应 Response response = mOkClient.newCall(request).execute(); if (response.isSuccessful()) { System.out.println(response.body().string()); } } catch (IOException e) { e.printStackTrace(); } }}
异步执行
通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()和cancel()等方法。
将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。
public class Main { private static OkHttpClient mOkClient = new OkHttpClient(); private final static String URL_STR = "https://www.baidu.com"; public static void main(String[] args) { // 创建请求对象 Request request = new Builder().url(URL_STR).build(); // 创建回调对象,用于请求后的回调 Call call = mOkClient.newCall(request); call.enqueue(new Callback() { // 收到响应时回调 @Override public void onResponse(Call call, Response reponse) throws IOException { String htmlBody = reponse.body().string(); System.out.println(htmlBody); } // 没有收到响应时回调,响应失败 @Override public void onFailure(Call arg0, IOException arg1) { } }); }}
通过response.string(),以字符串的形式 描述响应,response.bytes()以字节数组的形式描述响应
,response.inputstream(),获取该响应的输入流(支持大文件的读取)
如果响应体超过1MB,应该使用流进行存取(string会将文件加载到内存中)
输出结果(两种执行方式均相同)
<html><head> <script> location.replace(location.href.replace("https://","http://")); </script></head><body> <noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript></body></html>
POST 方式,携带参数
构建POST请求
Request request = new Request.Builder() .url("https://www.baidu.com") .header("User-Agent", "OkHttp Headers.java") .addHeader("Accept", "application/json; q=0.5") .addHeader("Accept", "application/vnd.github.v3+json") .build();
此处除了构造request对象略有不同之外,其他与GET请求均相同
public class Main2 { private static OkHttpClient mOkHttpClient = new OkHttpClient(); private static String URL = "https://www.baidu.com"; public static void main(String[] args) { // 构造post参数 okhttp3.x中的方法 FormBody body = new FormBody.Builder().add("key", "value").build(); Request request = new Request.Builder().url(URL).build(); // 其他与GET请求相同,这里仅用同步方式测试 try { Response response = mOkHttpClient.newCall(request).execute(); if (response.isSuccessful()) { System.out.println(response.code()); System.out.println(response.body().string()); } } catch (IOException e) { e.printStackTrace(); } }}
打印响应头
// 打印响应头Headers headers = response.headers();for (int i = 0; i < headers.size(); i++) { System.out.println(headers.name(i) + " : " + headers.value(i));}/* Server : nginx/1.4.6 (Ubuntu) Date : Fri, 27 May 2016 01:43:43 GMT Content-Type : text/plain Content-Length : 1759 Last-Modified : Tue, 27 May 2014 02:35:47 GMT Connection : keep-alive ETag : "5383fa03-6df" Accept-Ranges : bytes*/
响应缓存
为了缓存响应,你需要一个你可以读写的缓存目录,和缓存大小的限制。这个缓存目录应该是私有的,不信任的程序应不能读取缓存内容。
一个缓存目录同时拥有多个缓存访问是错误的。大多数程序只需要调用一次new OkHttp(),在第一次调用时配置好缓存,
然后其他地方只需要调用这个实例就可以了。否则两个缓存示例互相干扰,破坏响应缓存,而且有可能会导致程序崩溃。
响应缓存使用HTTP头作为配置。你可以在请求头中添加Cache-Control: max-stale=3600 ,OkHttp缓存会支持。
你的服务通过响应头确定响应缓存多长时间,例如使用Cache-Control: max-age=9600。
public class Main3 { // 设置缓存目录 private static File CACHE_DIR = new File("./cache"); public static void main(String[] args) { int cacheSize = 1024 * 1024 * 10; // 1MB // 创建Okhttpclient对象 OkHttpClient.Builder builder = new OkHttpClient.Builder(); // 创建缓存 注意okhttp3.3创建缓存的方法和2.X版本有很大不同,需在Okhttpclient对象中创建 Cache cache = new Cache(CACHE_DIR, cacheSize); builder.cache(cache); OkHttpClient client = builder.build(); // 使用新线程开始请求 new Thread() { public void run() { try { execute(client); } catch (Exception e) { e.printStackTrace(); } }; }.start(); } /** * 使用requset建立请求 */ public static void execute(OkHttpClient client) throws Exception { Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build(); Response response1 = client.newCall(request).execute(); if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1); String response1Body = response1.body().string(); System.out.println("Response 1 response: " + response1); System.out.println("Response 1 cache response: " + response1.cacheResponse()); System.out.println("Response 1 network response: " + response1.networkResponse()); request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build(); // 再次建立请求 Response response2 = client.newCall(request).execute(); if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2); String response2Body = response2.body().string(); System.out.println("Response 2 response: " + response2); System.out.println("Response 2 cache response: " + response2.cacheResponse()); System.out.println("Response 2 network response: " + response2.networkResponse()); // 如果为同一个对象,则缓存有效 System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body)); }}/* 结果: Response 1 response: Response{protocol=http/1.1, code=200, message=OK, url=https://publicobject.com/helloworld.txt} Response 1 cache response: null Response 1 network response: Response{protocol=http/1.1, code=200, message=OK, url=https://publicobject.com/helloworld.txt} Response 2 response: Response{protocol=http/1.1, code=200, message=OK, url=https://publicobject.com/helloworld.txt} Response 2 cache response: Response{protocol=http/1.1, code=200, message=OK, url=https://publicobject.com/helloworld.txt} Response 2 network response: null Response 2 equals Response 1? true */
此结果表明,缓存被重用
缓存文件
取消操作
网络操作中,经常会使用到对请求的cancel操作,okhttp的也提供了这方面的接口,call的cancel操作。
使用Call.cancel()可以立即停止掉一个正在执行的call。如果一个线程正在写请求或者读响应,将会引发IOException,
同时可以通过Request.Builder.tag(Object tag)给请求设置一个标签,
并使用OkHttpClient.cancel(Object tag)来取消所有带有这个tag的call。
但如果该请求已经在做读写操作的时候,cancel是无法成功的,会抛出IOException异常。
public class Main4 { private static OkHttpClient client = new OkHttpClient(); public static void main(String[] args) { // 这个Http请求会延时2秒 Request request = new Request.Builder().url("http://httpbin.org/delay/2").build(); Call call = client.newCall(request); long startTime = System.nanoTime(); // 系统当前时间戳 // 在1秒的时候取消请求 new Timer().schedule(new TimerTask() { @Override public void run() { System.out.printf("%.2f Canceling call.%n", (System.nanoTime() - startTime) / 1e9f); call.cancel(); System.out.printf("%.2f Canceled call.%n", (System.nanoTime() - startTime) / 1e9f); } // 此处将关闭时间设置5秒左右(视网络情况而定),输出结果为关闭失败 // 此处将关闭时间设置为2秒以内,输出为关闭成功,会捕获到 java.net.SocketException }, 2000); // second mills // 开始执行请求 try { System.out.printf("%.2f Executing call.%n", (System.nanoTime() - startTime) / 1e9f); Response response = call.execute(); System.out.printf("call is cancel:" + call.isCanceled() + "%n"); System.out.printf("%.2f Call was expected to fail, but completed: %s%n", (System.nanoTime() - startTime) / 1e9f, response); } catch (IOException e) { // 捕获到异常,表示取消请求 System.out.printf("%.2f Call failed as expected: %s%n", (System.nanoTime() - startTime) / 1e9f, e); } }}// 设置参数不同,此时会有两种可能/* 关闭失败,此时已结束IO 0.00 Executing call. call is cancel:false 2.94 Call was expected to fail, but completed: Response{protocol=http/1.1, code=200, message=OK, url=http://httpbin.org/delay/2} 10.00 Canceling call. 10.00 Canceled call. *//* 关闭成功,此时尚未接收响应 0.00 Executing call. 2.00 Canceling call. 2.00 Canceled call. 2.02 Call failed as expected: java.net.SocketException: Socket operation on nonsocket: configureBlocking */
基础的使用先介绍到这里,随后会介绍更复杂的用法。
- okhttp框架的使用
- OKHttp框架的使用
- Okhttp框架的使用
- OkHttp框架的简单使用
- okhttp网络框架的使用
- OkHttp网络框架的使用
- Android中OKHttp框架的使用
- okhttp网络请求框架的简单使用
- 【Android - 框架】之OkHttp的使用
- Android中OKHttp框架的使用
- Android网络请求框架的使用okhttp
- OkHttp(第三方框架)的使用
- 网络请求框架okhttp的使用
- Okhttp网络通信框架的使用
- OkHttp网络请求框架的使用
- okHttp开发框架使用
- Okhttp框架缓存使用
- android 开发 - 使用okhttp框架封装的开发框架
- java对cookie的操作
- 调试器如何工作(2)
- pods安装
- 面向对象 —— 类设计(十二)—— 全局变量和成员变量
- CocoaPods添加第三方库报错
- okhttp框架的使用
- Eclipse SVN冲突解决
- nodejs之初识模块化
- PostgreSQL实用日常维护SQL
- Android Launcher浅析(一)
- opencv图像相似度的计算方法
- Android中Toolbar的基本使用
- MyBatis中关于resultType和resultMap的区别
- PowerPoint如何带走自己的字体