okhttp的使用

来源:互联网 发布:剑网3和尚脸型数据 编辑:程序博客网 时间:2024/06/03 06:12

在学习Android的过程中,官方集成网络框架就包含了HttpUrlConnection、HttpClient、Volley,其中Volley是android开发团队在2013年Google I/O大会上推出了一个新的网络通信框架,目前Volley中部分代码仍然借助于HttpClient中部分功能,然而HttpClient在Android最新版本6.0中已经被剔除掉了,如果想要使用Volley还必须使用一个第三方的jai包org.apache.http.legacy.jar,再者Volley是针对数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。如果开发中使用HttpUrlConnection则要从头开始封装对应得操作,所以最近转向了一个第三方网络请求框架OkHttp,本文所介绍的示例都是针对OkHttp3.0库。

OkHttp

OkHttp是一个 Java 的 HTTP+SPDY 客户端开发包,同时也支持 Android。需要Android 2.3以上, OkHttp github源码 ,同时还需要一个 okio包

OKHttp是Android版Http客户端。非常高效,支持SPDY、连接池、GZIP和 HTTP 缓存;
默认情况下,OKHttp会自动处理常见的网络问题,像二次连接、SSL的握手问题;
如果你的应用程序中集成了OKHttp,Retrofit默认会使用OKHttp处理其他网络层请求;
从Android4.4开始HttpURLConnection的底层实现采用的是okHttp。
OkHttp的简单使用

OkHttp建立一个网络请求可以是异步的也可以是同步的,大体上分为三个步骤:

新建一个OkHttpClient对象,可以直接new一个OkHttpClient,也可以使用建造者模式build一个,事实上new一个新的内部也是调用的build方式构建出来的。
Java

public OkHttpClient() {
this(new Builder());
}
public OkHttpClient() {
this(new Builder());
}
通过Request.Builder对象新建一个Request对象,仍然使用的是建造者模式;
返回执行结果,同步请求和异步请求在这里才有区别,在执行请求之前,上面两个步骤都是一样的。
OkHttp同步请求

Java

//步骤1
OkHttpClient client = new OkHttpClient();

//步骤2
Request request = new Request.Builder().url(url).build();

//步骤3
Response response = client.newCall(request).execute();
if(response.isSuccessful()){
String result = response.body().string();
System.out.println(result);
}
//步骤1
OkHttpClientclient = new OkHttpClient();

//步骤2
Requestrequest = new Request.Builder().url(url).build();

//步骤3
Responseresponse = client.newCall(request).execute();
if(response.isSuccessful()){
String result = response.body().string();
System.out.println(result);
}
这里建立的默认请求采用的是get方式请求的,源码如下:

Java

public Builder() {
this.method = “GET”;
this.headers = new Headers.Builder();
}
public Builder() {
this.method = “GET”;
this.headers = new Headers.Builder();
}
OkHttp异步请求

与同步请求不同之处就在步骤三中,步骤三代码如下:

Java

//步骤3
client.newCall(request).enqueue(new Callback() {

@Override
public void onFailure(Call call, IOException e) {

}

@Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().string();
System.out.println(result);
}

});
//步骤3
client.newCall(request).enqueue(new Callback() {

@Override
public void onFailure(Callcall, IOException e) {

}

@Override
public void onResponse(Callcall, Responseresponse) throws IOException {
String result = response.body().string();
System.out.println(result);
}

});
注意:虽然这里是异步请求,但是这里的回调函数确是在子线程中执行的回调,在Android开发中如果想将回调放入主线程中,因为只有在主线程中才能更新UI,我们一般会借助于Handler消息机制来处理,以前写过一篇文章Handler机制,一般Looper在哪个线程,它处理的消息就在哪个线程。

Java

//新建一个Handler实例
Handler handler = new Handler(Looper.getMainLooper());
//自定义一个接口回调
public interface RequestCallback {

void onStart();

void onSuccess(String result);

void onFailure(ErrorType errorType);

}
//设置转换为主线程的回调
httpClient.newCall(request).enqueue(new Callback() {
public void onResponse(Response response) throws IOException {
if (response.isSuccessful()) {
final String result = response.body().string();
handler.post(new Runnable() {
public void run() {
callback.onSuccess(result);
}
});
}
}

public void onFailure(Request req, final IOException e) {
handler.post(new Runnable() {
public void run() {
callback.onFailure(ErrorType.SERVER);
}
});
}
});
//新建一个Handler实例
Handlerhandler = new Handler(Looper.getMainLooper());
//自定义一个接口回调
public interface RequestCallback {

void onStart();

void onSuccess(String result);

void onFailure(ErrorTypeerrorType);

}
//设置转换为主线程的回调
httpClient.newCall(request).enqueue(new Callback() {
public void onResponse(Responseresponse) throws IOException {
if (response.isSuccessful()) {
final String result = response.body().string();
handler.post(new Runnable() {
public void run() {
callback.onSuccess(result);
}
});
}
}

public void onFailure(Requestreq, final IOException e) {
handler.post(new Runnable() {
public void run() {
callback.onFailure(ErrorType.SERVER);
}
});
}
});
get请求url转码

在处理get请求是我们要对url中需要传入的参数进行Encoder处理,主要是为了处理传输过程中的特殊字符如中文或者空格等。

Java

public static String buildQueryUrl(String uri, List params) {
StringBuilder queryBuilder = new StringBuilder(uri);
if (!uri.contains(“?”)) {
queryBuilder.append(“?”);
} else if (!uri.endsWith(“?”)) {
queryBuilder.append(“&”);
}
List queryParams = params;
if (queryParams != null) {
for (KeyValue kv : queryParams) {
String name = kv.key;
String value = kv.getValueStr();
if (!TextUtils.isEmpty(name) && value != null) {
queryBuilder.append(Uri.encode(name, “utf-8”)).append(“=”).append(Uri.encode(value, “utf-8”)).append(“&”);
}
}
}

if (queryBuilder.charAt(queryBuilder.length() - 1) == ‘&’) {
queryBuilder.deleteCharAt(queryBuilder.length() - 1);
}

if (queryBuilder.charAt(queryBuilder.length() - 1) == ‘?’) {
queryBuilder.deleteCharAt(queryBuilder.length() - 1);
}
return queryBuilder.toString();
}
public static String buildQueryUrl(String uri, List params) {
StringBuilderqueryBuilder = new StringBuilder(uri);
if (!uri.contains(“?”)) {
queryBuilder.append(“?”);
} else if (!uri.endsWith(“?”)) {
queryBuilder.append(“&”);
}
List queryParams = params;
if (queryParams != null) {
for (KeyValuekv : queryParams) {
String name = kv.key;
String value = kv.getValueStr();
if (!TextUtils.isEmpty(name) && value != null) {
queryBuilder.append(Uri.encode(name, “utf-8”)).append(“=”).append(Uri.encode(value, “utf-8”)).append(“&”);
}
}
}

if (queryBuilder.charAt(queryBuilder.length() - 1) == ‘&’) {
queryBuilder.deleteCharAt(queryBuilder.length() - 1);
}

if (queryBuilder.charAt(queryBuilder.length() - 1) == ‘?’) {
queryBuilder.deleteCharAt(queryBuilder.length() - 1);
}
return queryBuilder.toString();
}
其中KeyValue就是一个JavaBean,也可以中Map代替,本文KeyValue代码来自xUtils3。

Java

public class KeyValue {
public final String key;
public final Object value;

public KeyValue(String key, Object value) {    this.key = key;    this.value = value;}public String getValueStr() {    return value == null ? null : value.toString();}@Overridepublic boolean equals(Object o) {    if (this == o) return true;    if (o == null || getClass() != o.getClass()) return false;    KeyValue keyValue = (KeyValue) o;    return key == null ? keyValue.key == null : key.equals(keyValue.key);}@Overridepublic int hashCode() {    return key != null ? key.hashCode() : 0;}@Overridepublic String toString() {    return "KeyValue{" + "key='" + key + '\'' + ", value=" + value + '}';}

}
public class KeyValue {
public final String key;
public final Object value;

public KeyValue(String key, Object value) {    this.key = key;    this.value = value;}public String getValueStr() {    return value == null ? null : value.toString();}@Overridepublic boolean equals(Object o) {    if (this == o) return true;    if (o == null || getClass() != o.getClass()) return false;    KeyValuekeyValue = (KeyValue) o;    return key == null ? keyValue.key == null : key.equals(keyValue.key);}@Overridepublic int hashCode() {    return key != null ? key.hashCode() : 0;}@Overridepublic String toString() {    return "KeyValue{" + "key='" + key + '\'' + ", value=" + value + '}';}

}
下面是一个url简单的示例:

Java

List list = new ArrayList();
list.add(new KeyValue(“name”, “木子”));
list.add(new KeyValue(“pwd”, “123456”));
String uri = “http://192.168.0.117:8080/cookie/get?isLogin=true“;
uri = ParamUtils.buildQueryUrl(uri, list);
List list = new ArrayList();
list.add(new KeyValue(“name”, “木子”));
list.add(new KeyValue(“pwd”, “123456”));
String uri = “http://192.168.0.117:8080/cookie/get?isLogin=true“;
uri = ParamUtils.buildQueryUrl(uri, list);
转码后输入结果为:

http://192.168.0.117:8080/cookie/get?isLogin=true&name=%E6%9C%A8%E5%AD%90&pwd=123456

post请求

这里所讲的post请求,仅仅限制在表单提交中,也就是content-type为” application/x-www-form-urlencoded”的请求,其余的方式如文件上传下次再做介绍。对于post方式提交表单,OkHttp已经封装好了相应的类FormBody来设置表单的参数,示例代码如下:

Java

//步骤1
OkHttpClient client = new OkHttpClient();

//步骤2
RequestBody formBody = new FormBody.Builder().add(“name”, “木子”).add(“pwd”, “123456”).build();
Request request = new Request.Builder().url(uri).post(formBody).build();

//步骤3
client.newCall(request).enqueue(new Callback() {

@Override
public void onFailure(Call call, IOException e) {

}
@Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().string();
}

});
//步骤1
OkHttpClientclient = new OkHttpClient();

//步骤2
RequestBodyformBody = new FormBody.Builder().add(“name”, “木子”).add(“pwd”, “123456”).build();
Requestrequest = new Request.Builder().url(uri).post(formBody).build();

//步骤3
client.newCall(request).enqueue(new Callback() {

@Override
public void onFailure(Callcall, IOException e) {

}
@Override
public void onResponse(Callcall, Responseresponse) throws IOException {
String result = response.body().string();
}

});

0 0
原创粉丝点击