OkHttp是一个关于网络请求的第三方类库,其中封装了网络请求的get、post等操做的底层实现,是Android端目前最为火热的网络请求框架之一。java
在Android Studio中不须要下载专门的jar包,直接在gradle中添加依赖,以下所示:bash
compile 'com.squareup.okhttp3:okhttp:3.10.0'
复制代码
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http:www.taobao.com").build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
Log.d("ABC", "response=" + response.body().toString());
// 转到UI线程去修改UI
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
复制代码
get同步请求分为三步: 首先使用new建立OkHttpClient对象。 而后调用OkHttpClient对象的newCall方法生成一个Call对象,该方法接收一个Request对象,Request对象存储的就是咱们的请求URL和请求参数。 最后执行Call对象的execute方法,获得Response对象,这个Response对象就是返回的结果。服务器
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://www.tabao.com").build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d("ABC", "error");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.d("ABC", "response=" + response.body().toString());
// 转到UI线程去修改UI
}
}
});
复制代码
get异步请求分为三步: 首先使用new建立OkHttpClient对象。 而后调用OkHttpClient对象的newCall方法生成一个Call对象,该方法接收一个Request对象,Request对象存储的是咱们的请求URL和请求参数。 最后执行Call对象的enqueue方法,该方法接收一个Callback回调对象,在回调对象的onResponse方法中拿到Response对象,这就是返回的结果。网络
总结:get的同步方法和异步方法的差异在于同步方法须要手动开启一个线程执行,而异步方法不须要(实际上是使用了内部的线程)。框架
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient();
FormBody.Builder formBody = new FormBody.Builder();
formBody.add("bookName", "Android Art");
Request request = new Request.Builder().url("http:www.taobao.com").post(formBody.build()).build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
Log.d("ABC", "response=" + response.body().toString());
// 转到UI线程去修改UI
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
复制代码
对比:post方法的同步请求和get方法的同步请求的区别在于,post方法生成Request对象时多执行了post(RequestBody)方法,而RequestBody对象的子类是FormBody类,因此可使用FormBody对象建立键值对参数。异步
再深刻一步,为何post请求须要执行post方法,并且get请求不用呢?咱们看一下post方法里面执行了什么操做?ide
public Builder post(RequestBody body) {
return method("POST", body);
}
复制代码
返回了method方法的执行结果,这里传递了一个“POST”字符串,看一下method方法的执行:函数
public Builder method(String method, RequestBody body) {
if (method == null) throw new NullPointerException("method == null");
if (method.length() == 0) throw new IllegalArgumentException("method.length() == 0");
if (body != null && !HttpMethod.permitsRequestBody(method)) {
throw new IllegalArgumentException("method " + method + " must not have a request body.");
}
if (body == null && HttpMethod.requiresRequestBody(method)) {
throw new IllegalArgumentException("method " + method + " must have a request body.");
}
this.method = method;
this.body = body;
return this;
}
复制代码
这里将“POST"字符串传递给了Builder对象的method变量,而Builder的默认构造函数中将method变量赋值为"GET"。到这里就水落石出了,原来Request.Builder对象建立时,默认就是get请求,因此get请求就不用设置get方法了,而post请求则须要修改method变量的值为"POST"。post
OkHttpClient client = new OkHttpClient();
FormBody.Builder formBody = new FormBody.Builder();
formBody.add("bookName", "Android Art");
Request request = new Request.Builder().url("http://www.tabao.com").post(formBody.build()).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d("ABC", "error");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.d("ABC", "response=" + response.body().toString());
// 转到UI线程去修改UI
}
}
});
复制代码
Retrofit是一个RESTful的HTTP网络请求框架,它是基于OkHttp的。它是经过注解配置网络参数的,支持多种数据的解析和序列化(Gson、Json、Xml等,而且对RxJava也是支持的。下面是Retrofit和OkHttp的联系图(图来自于https://blog.csdn.net/carson_ho/article/details/73732076): gradle
在Android Studio中Retrofit库的依赖,因为其还依赖了OkHttp库,因此同时须要添加OkHttp的依赖。
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.okhttp3:okhttp:3.8.1'
复制代码
Retrofit使用注解的方式描述和配置网络请求参数。其实是运用动态代理的方式将注解翻译成一个Http请求,而后执行该请求。基本的结构以下:
public interface GitHubService {
@GET("getUserData")
Call<User> getCall();
}
复制代码
User.java
public class User {
private int userId;
private String userName;
private ExInfo exInfo;
private static class ExInfo {
private String from;
private String birthDay;
}
public void show() {
Log.d("ABC", "userId=" + userId);
Log.d("ABC", "userName=" + userName);
Log.d("ABC", "from=" + exInfo.from);
Log.d("ABC", "birthday=" + exInfo.birthDay);
}
}
复制代码
注意项: 一、这是一个接口(Interface)不是一个类(class)。 二、其中能够建立不一样的接口方法。 三、每个接口方法和接口方法的参数必须使用注解的方式标注,不然会报错。 四、请求方法有GET、POST、PUT、HEAD、DELETE等。 五、方法的返回类型必须为Call,xxx是接收数据的类(能够是咱们自定义的类,也能够是ResponseBody)。 六、User中字段的名字必须和后台Json定义的字段名是一致的,这样Json才能解析成功。
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://10.75.114.138:8081/")
.addConverterFactory(GsonConverterFactory.create()).build(); //设置网络请求的Url地址
.addConverterFactory(GsonConverterFactory.create()) //设置数据解析器
.build();
复制代码
网络请求的地址:建立Retrofit对象时经过baseUrl()设置+网络请求接口的注解设置。 addConverterFactory(GsonConverterFactory.create())的做用是设置数据解析器,它能够解析Gson、JsonObject、JsonArray这三种格式的数据。
// 建立 网络请求接口 的实例
GitHubServiceRequest request = retrofit.create(GitHubService.class);
//对 发送请求 进行封装
Call<Reception> call = request.getCall();
复制代码
同步请求:
// 发送网络请求(同步)
Response<Reception> response = call.execute();
复制代码
异步请求:
call.enqueue(new Callback<User>() {
//请求成功后回调
@Override
public void onResponse(Call<User> call, Response<User> response) {
//处理请求结果
User user = response.body();
if(user != null) {
user.show();
}
}
//请求失败后回调
@Override
public void onFailure(Call<User> call, Throwable throwable) {
System.out.println("请求失败");
}
});
复制代码
Retrofit的一个RESTful风格的网络请求框架,其下一层的实现也是OkHttp,因此其原理和OkHttp的同样的,只是在OkHttp的上面封装了一层,使请求接口和数据解析更加简洁明了。