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
能夠看到App應用層是經過Retrofit請求網絡,而後使用Retrofit接口層封裝請求參數、Header、URL等信息,而後由OkHttp完成後續的和服務器的交互。 而服務器返回響應數據後,也是先返回給OkHttp,而後OkHttp將原始結果返回給Retrofit,Retrofit根據用戶的需求對原始數據進行解析封裝,並返回給App應用層。在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的上面封裝了一層,使請求接口和數據解析更加簡潔明瞭。