Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient。但HttpURLConnection太难用,而Google又在Android 6.0删除了HttpClient的相关API,那么有没有更好用的http请求客户端呢,答案是肯定的,那就是OkHttp,大名鼎鼎的Square开发的,你值得拥有。
OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。
下面简单说下怎么使用:
1.导包,使用AS的话直接在gradle中进行配置,由于OkHttp依赖OkIO所以想要的Okio也要导入:
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okio:okio:1.9.0'
2.简单的get请求
请求分2种,异步enqueue()和同步execute(),同步请求会阻塞线程,但是异步请求的onResponse工作在子线程中,所以要更新UI需要使用Handler。
onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()
获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes()
;如果你想拿到返回的inputStream,则调用response.body().byteStream()
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://www.baidu.com").build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println("rep >>> " + response.body().string());
}
});
3.简单的post请求
3.1 携带参数,提交键值对
okhttp3.FormBody instead of FormEncodingBuilder.(OkHttp3.x,FormEncodingBuilder已被FormBody取代)
OkHttpClient client = new OkHttpClient();
FormBody body = new FormBody.Builder()
.add("a","上海市")
.add("aa","松江区")
.add("aaa","车墩镇")
.build();
Request request = new Request.Builder()
.url("http://gc.ditu.aliyun.com/geocoding")
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println("rep >>> " + response.body().string());
}
});
3.2 提交字符串数据,但不建议发送超过1M的文本信息
public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("\"application/json; charset=utf-8\"");
OkHttpClient client = new OkHttpClient();
String json = "{'username':'张三','age':'18','sex':'男'}";
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON,json);
Request request = new Request.Builder()
.url("http://gc.ditu.aliyun.com/geocoding")
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println("rep >>> " + response.body().string());
}
});<span style="color:#FF0000;"><span style="background-color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 0, 0);"><span style="background-color: rgb(255, 255, 255);"><span style="color:#FFFFFF;">
3</span></span></span></span></span>
<span style="color:#FF0000;"><span style="background-color: rgb(255, 0, 0);"></span></span>
3.3 提交一个文件
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");
OkHttpClient client = new OkHttpClient();
File file = new File("README.md");
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
4. 通过OkHttpClient设置请求超时时间,缓存,拦截器,代理,SSL,验证等配置
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
5. 通过Request设置请求头信息
okhttp3
添加请求头,需要在Request.Builder()
使用.header(String key,String value)
或者.addHeader(String key,String value)
;
使用.header(String key,String value)
,如果key已经存在,将会移除该key对应的value,然后将新value添加进来,即替换掉原来的value;
使用.addHeader(String key,String value)
,即使当前的可以已经存在值了,只会添加新value的值,并不会移除/替换原来的值。
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();
6. 认证
OkHttp会自动重试未验证的请求。当响应是401 Not Authorized
时,Authenticator
会被要求提供证书。
OkHttpClient client = new OkHttpClient.Builder()
.authenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
String auth = Credentials.basic("username", "password");
return response.request().newBuilder().header("Authorization",auth).build();
}
})
.build();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});