OKHttp使用简单介绍
如今android网络方面的第三方库非常多,volley。Retrofit。OKHttp等,各有各自的特点,这边博客就来简介下怎样使用OKHttp。
梗概
OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟。还有透明的GZIP压缩。请求缓存等优势 OKHttp官网
配置环境
支持Android 2.3及其以上版本号。要求java JDK1.7以上
jar包引入
能够通过下载jar包直接导入project地址例如以下下载地址
或者通过构建的方式导入
MAVEN:
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.4.0</version>
</dependency>
GRADLE
compile 'com.squareup.okhttp:okhttp:2.4.0'
使用方法
在向网络发起请求的时候,我们最常常使用的就是GET和POST。以下就来看看怎样使用
1. GET
在OKHttp,每次网络请求就是一个Request,我们在Request里填写我们须要的url,header等其它參数,再通过Request构造出Call,Call内部去请求參数,得到回复,并将结果告诉调用者。
package com.jackchan.test.okhttptest;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.File;
import java.io.IOException;
public class TestActivity extends ActionBarActivity {
private final static String TAG = "TestActivity";
private final OkHttpClient client = new OkHttpClient();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
new Thread(new Runnable() {
@Override
public void run() {
try {
execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void execute() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();
if(response.isSuccessful()){
System.out.println(response.code());
System.out.println(response.body().string());
}
}
}
我们通过Request.Builder传入url,然后直接execute运行得到Response,通过Response能够得到code,message等信息。
这个是通过同步的方式去操作网络请求,而android本身是不同意在UI线程做网络请求操作的,因此我们须要自己开启一个线程。
当然,OKHttp也支持异步线程而且有回调返回。有了上面同步的基础,异步仅仅要稍加修改即可
private void enqueue(){
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
//NOT UI Thread
if(response.isSuccessful()){
System.out.println(response.code());
System.out.println(response.body().string());
}
}
});
}
就是在同步的基础上讲execute改成enqueue,而且传入回调接口,但接口回调回来的代码是在非UI线程的,因此假设有更新UI的操作记得用Handler或者其它方式。
2、POST
说完GET该介绍些怎样使用POST,POST情况下我们一般须要传入參数,甚至一些header。传入參数或者header
比方传入header
Request request = new Request.Builder()
.url("https://api.github.com/repos/square/okhttp/issues")
.header("User-Agent", "OkHttp Headers.java")
.addHeader("Accept", "application/json; q=0.5")
.addHeader("Accept", "application/vnd.github.v3+json")
.build();
传入POST參数
RequestBody formBody = new FormEncodingBuilder()
.add("platform", "android")
.add("name", "bug")
.add("subject", "XXXXXXXXXXXXXXX")
.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
能够看出来,传入header或者post參数都是传到Request里面。因此最后的调用方式也和GET方式一样
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
这个代码是同步网络请求。异步就改成enqueue即可了。
请求缓存
在网络请求中。缓存技术是一项应用比較广泛的技术,须要对请求过的网络资源进行缓存。而okhttp也支持这一技术,也使用十分方便。前文涨常常出现的OkHttpclient这个时候就要派送用场了。
看以下代码
package com.jackchan.test.okhttptest;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import java.io.File;
import java.io.IOException;
public class TestActivity extends ActionBarActivity {
private final static String TAG = "TestActivity";
private final OkHttpClient client = new OkHttpClient();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
File sdcache = getExternalCacheDir();
int cacheSize = 10 * 1024 * 1024; // 10 MiB
client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
new Thread(new Runnable() {
@Override
public void run() {
try {
execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void execute() 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());
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));
}
}
okhttpclient有点像Application的概念,统筹着整个okhttp的大功能。通过它设置缓存文件夹。我们运行上面的代码,得到的结果例如以下
response1 的结果在networkresponse。代表是从网络请求载入过来的,而response2的networkresponse 就为null,而cacheresponse有数据,由于我设置了缓存因此第二次请求时发现缓存里有就不再去走网络请求了。
但有时候即使在有缓存的情况下我们依旧须要去后台请求最新的资源(比方资源更新了)这个时候能够使用强制走网络来要求必须请求网络数据
public void execute() 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_NETWORK).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));
}
上面的代码中
response2相应的request变成
request = request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build();
我们看看运行结果
response2的cache response为null,network response依旧有数据。
相同的我们能够使用 FORCE_CACHE 强制仅仅要使用缓存的数据,但假设请求必须从网络获取才有数据。但又使用了FORCE_CACHE 策略就会返回504错误。代码例如以下,我们去okhttpclient的缓存,并设置request为FORCE_CACHE
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
File sdcache = getExternalCacheDir();
int cacheSize = 10 * 1024 * 1024; // 10 MiB
//client.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
new Thread(new Runnable() {
@Override
public void run() {
try {
execute();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage().toString());
}
}
}).start();
}
public void execute() 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));
}
取消操作
网络操作中,常常会使用到对请求的cancel操作,okhttp的也提供了这方面的接口,call的cancel操作。使用Call.cancel()能够马上停止掉一个正在运行的call。
假设一个线程正在写请求或者读响应。将会引发IOException,同一时候能够通过Request.Builder.tag(Object tag)给请求设置一个标签,并使用OkHttpClient.cancel(Object tag)来取消全部带有这个tag的call。
但假设该请求已经在做读写操作的时候,cancel是无法成功的,会抛出IOException异常。
public void canceltest() throws Exception {
Request request = new Request.Builder()
.url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay.
.build();
final long startNanos = System.nanoTime();
final Call call = client.newCall(request);
// Schedule a job to cancel the call in 1 second.
executor.schedule(new Runnable() {
@Override
public void run() {
System.out.printf("%.2f Canceling call.%n", (System.nanoTime() - startNanos) / 1e9f);
call.cancel();
System.out.printf("%.2f Canceled call.%n", (System.nanoTime() - startNanos) / 1e9f);
}
}, 1, TimeUnit.SECONDS);
try {
System.out.printf("%.2f Executing call.%n", (System.nanoTime() - startNanos) / 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() - startNanos) / 1e9f, response);
} catch (IOException e) {
System.out.printf("%.2f Call failed as expected: %s%n",
(System.nanoTime() - startNanos) / 1e9f, e);
}
}
成功取消
取消失败
简单的对于OKHttp的使用就介绍到这里。下次将重点从源代码角度介绍整个OKHttp是怎样运转的。
上面部分的代码,我已经上传到github,各位看官有须要能够自行去下载源代码下载
OKHttp使用简单介绍的更多相关文章
- Https系列之一:https的简单介绍及SSL证书的生成
Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http ...
- [原创]关于mybatis中一级缓存和二级缓存的简单介绍
关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...
- 利用Python进行数据分析(7) pandas基础: Series和DataFrame的简单介绍
一.pandas 是什么 pandas 是基于 NumPy 的一个 Python 数据分析包,主要目的是为了数据分析.它提供了大量高级的数据结构和对数据处理的方法. pandas 有两个主要的数据结构 ...
- 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍
一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...
- yii2的权限管理系统RBAC简单介绍
这里有几个概念 权限: 指用户是否可以执行哪些操作,如:编辑.发布.查看回帖 角色 比如:VIP用户组, 高级会员组,中级会员组,初级会员组 VIP用户组:发帖.回帖.删帖.浏览权限 高级会员组:发帖 ...
- angular1.x的简单介绍(二)
首先还是要强调一下DI,DI(Denpendency Injection)伸手获得,主要解决模块间的耦合关系.那么模块是又什么组成的呢?在我看来,模块的最小单位是类,多个类的组合就是模块.关于在根模块 ...
- Linux的简单介绍和常用命令的介绍
Linux的简单介绍和常用命令的介绍 本说明以Ubuntu系统为例 Ubuntu系统的安装自行百度,或者参考http://www.cnblogs.com/CoderJYF/p/6091068.html ...
- iOS-iOS开发简单介绍
概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...
- iOS开发多线程篇—多线程简单介绍
iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcod ...
随机推荐
- BZOJ 3672 [NOI2014]购票 (凸优化+树剖/树分治)
题目大意: 略 题面传送门 怎么看也是一道$duliu$题= = 先推式子,设$dp[x]$表示到达$x$点到达1节点的最小花费 设$y$是$x$的一个祖先,则$dp[x]=min(dp[y]+(di ...
- 关于fromkeys的用法
分享一个小知识点: 1. Python 中关于dict的fromkeys方法: 1. fromkeys是用于重构字典 2. 至少传一个参数,第一个参数为新建dict的key,如果第一个参数为字典,那么 ...
- PL/SQL基本语法
*2.PL/SQL基本语法 1)匿名块 一段不能在数据库存储的PL/SQL. 基本结构如下: DECLARE //变量的声明定义区域(可省略) BEGIN //业务处理 ...
- 高级函数-case
case函数 (适合区间,>,<判断) case when 判断表达式 then when 判断表达式 then ..... end s ...
- javascript-js中技巧集合
1.值的转换 在JavaScript中,一共有两种类型的值:原始值(primitives)和对象值(objects).原始值有:undefined, null, 布尔值(booleans), 数字(n ...
- 使用Dagger2创建的第一个小样例
将Dagger系列的咖啡壶样例再做一下简化,作为Dagger2的入门的第一个小样例. 场景描写叙述:有一个电水壶,它使用一个加热器来烧水.电水壶具备的功能有:開始加热(on方法),结束加热(off方法 ...
- bzoj4554: [Tjoi2016&Heoi2016]游戏(二分图匹配)
4554: [Tjoi2016&Heoi2016]游戏 题目:传送门 题解: 一道很牛逼的匈牙利..和之前模拟赛的一道题有点相似(不过这题不用完美匹配) 我们可以把连续的行和列全部编号(如果之 ...
- php中echo什么时候用到\"这个符号
php中echo什么时候用到\"这个符号 当在引号中用到引号时,为避免混乱用\" \称为转义符,表示后面的字符和原来程序语言里的语法符号含义不同 常见的转义有 \" \' ...
- linux操作系统下完全删除oracle数据库
1.关掉oracle server 和 background processes ps -ef | grep ora 关掉数据库 shutdown immediate 2.关掉监听 lsnrctl ...
- angular4(2-2)angular脚手架引入第三方类库(swiper)
试了好多方法,npm install 方法失败了,下载到本地是可以使用的: 将swiper文件放到assets文件下: 项目目录下:(命令行) 因为ts并不能准确识别js语法,所以需要用ts中的int ...