前言
OkHttp是目前使用最廣泛的移動端網(wǎng)絡底層庫。在Volley魁巩、Retrofit等知名上層網(wǎng)絡庫中,都可以看到它的身影。即使在高版本的Android系統(tǒng)中的URLConnection中也可以看到它的身影峻村。?
因為,各大網(wǎng)絡庫對OkHttp進行了封裝锡凝。我們雖然使用方便粘昨,卻不免失去了一定的靈活性。如果OkHttp擁有的功能,上層庫卻沒有封裝张肾,我們在使用時芭析,就會比較麻煩。因此吞瞪,我們在這里嘗試直接使用OkHttp馁启,看看未經(jīng)封裝的OkHttp如何使用。
Request
OkHttp將請求封裝在了Request類中尸饺。我們大致看看Request的成員:
public final class Request{
private final HttpUrl url;
private final String method;
private final Headers headers;
private final RequestBody body;
private final Object tag;
}
其中HttpUrl
類代表請求地址, String method
代表請求方法, Headers
代表請求頭, RequestBody
代表請求體. Object tag
是用來取消http請求的標志, 這個我們先不管.
我們在使用OkHttp時已亥,我們可以用Request提供的Builder生成我們想要的Request。
final Request request = new Request.Builder().url("https://github.com/").build();
完成Request的創(chuàng)建后蓬网,我們可以調(diào)用:
final Request request = new Request.Builder().url("https://github.com/").build();
Response response = client.newCall(request).execute();
從Request
被調(diào)用的方式诞丽,我們可以發(fā)現(xiàn),這是一個同步網(wǎng)絡請求迹栓。請求完成后掉分,會直接返回Response
給我們。下面克伊,我們就來看看Response
的結(jié)構(gòu)酥郭。
Response
public final class Response{
private final Request request;
private final Protocol protocol;
private final int code;
private final String message;
private final HandShake handShake;
private final Headers headers;
private final ResponseBody body;
private Response networkResponse;
private Response cacheResponse;
private final Response priorResponse;
}
可以看到Response類里面有Protocol
代表請求協(xié)議, int code
代表響應碼, String message
代表描述信息, Headers
代表響應頭, ResponseBody
代表響應體. 當然除此之外, 還有Request
代表持有的請求, Handshake
代表SSL/TLS握手協(xié)議驗證時的信息, 這些額外信息我們暫時不問.
介紹完Request
和Response
兩個重要的類,下面我們可看看愿吹,OkHttp的各種請求的調(diào)用方法不从。
GET請求
同步GET
同步GET的意思是一直等待http請求, 直到返回了響應. 在這之間會阻塞進程, 所以通過get不能在Android的主線程中執(zhí)行, 否則會報錯。
private final OkHttpClient client = new OkHttpClient();
public void run() throw Exception{
Request request = new Request.Builder()
.url("https://github.com/")
.build();
Response response = client.newCall(request).execute();
}
異步GET
異步GET的意思是OkHttp會幫我們另外開啟后臺線程發(fā)送http請求犁跪,開啟后臺線程后椿息,不再阻礙當前線程的執(zhí)行。當http請求完成后坷衍,會以回調(diào)的方式寝优,將請求結(jié)果返回到當前線程。
private final OkHttpClient client = new OkHttpClient();
public void run() throw Exception{
Request request = new Request.Builder()
.url("https://github.com/")
.build();
Response response = client.newCall(request).enqueue(new Callback(){
@Override
public void onResponse(Response response) throw IOException{
}
@Override
public void onFailure(Request request , Throwable throwable){
}
});
}
POST請求
在上面的GET請求的介紹中枫耳,我們已經(jīng)分別介紹了同步請求和異常請求乏矾。在POST請求的介紹中,我們不再以同步和異步進行分類迁杨,只介紹同步情況钻心,而把精力集中在,POST上傳的內(nèi)容形式的分類上仑最。
POST提交String
private final OkHttpClient client = new OkHttpClient();
public void run() throw Exception{
String uploadInfo = "Need to Upload!";
Request request = new Request.Builder()
.url("https://github.com/")
.post(RequestBody.create("text/x-markdown; charset=utf-8" , uploadInfo))
.build();
Response response = client.newCall(request).execute();
}
POST提交文件
private final OkHttpClient client = new OkHttpClient();
public void run() throw Exception{
File file = new File("README.md")扔役;
Request request = new Request.Builder()
.url("https://github.com/")
.post(RequestBody.create("text/x-markdown; charset=utf-8" , file))
.build();
Response response = client.newCall(request).execute();
}
POST提交表單
private final OkHttpClient client = new OkHttpClient();
public void run() throw Exception{
RequestBody formBody = new formBody.Builder()
.add("user" , "oldFrog")
.build();
Request request = new Request.Builder()
.url("https://github.com/")
.post(formBody)
.build();
Response response = client.newCall(request).execute();
}
POST提交分塊請求
private final OkHttpClient client = new OkHttpClient();
public void run() throw Exception{
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("user" , "oldFrog")
.addFormDataPart("image" , "logo.png" , RequestBody.create(MEDIA_TYPE_PNG, new File("local_logo.png")))
.build();
Request request = new Request.Builder()
.url("https://github.com/")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
}
POST提交Stream
private static final MediaType MEDIA_TYPE_PLAINTEXT = MediaType
.parse("text/plain; charset=utf-8");
private final OkHttpClient client = new OkHttpClient();
@Test
public void testPostStream() throws Exception {
RequestBody requestBody = new RequestBody() {
@Override
public MediaType contentType() {
return MEDIA_TYPE_PLAINTEXT;
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
File file = new File("src/test/resources/Lorem Ipsum.txt");
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
sink.writeUtf8(line);
}
}
}
};
Request request = new Request.Builder()
.url("http://httpbin.org/post")
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
}
至此,就介紹了okhttp的基本使用警医。后面會開始分析okhttp的源碼亿胸,以深入其進階使用坯钦。
如有問題,歡迎指正侈玄。