本節前言
本來是想圍繞著HttpClient講解的,后來發先Android4.4之后okhttp代替了hc,所以將不再講解hc
okhttp的簡單使用,主要包含:
- 一般的get請求
- 一般的post請求
- 基于Http的文件上傳
- 文件下載
- 加載圖片
- 支持請求回調,直接返回對象、對象集合
- 支持session的保持
使用okhttp
使用okhttp前首先要添加依賴
compile 'com.squareup.okhttp3:okhttp:3.9.0'
一般的get請求
對了網絡加載庫,那么最常見的肯定就是http get請求了,比如獲取一個網頁的內容
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
String string = response.body().string();
System.out.println(string);
}
運行結果
以上就是發送一個get請求的步驟,首先構造一個Request對象,參數最起碼有個url,當然你可以通過Request.Builder設置更多的參數比如:header、method等。
然后通過request的對象去構造得到一個Call對象,類似于將你的請求封裝成了任務,既然是任務,就會有execute()和cancel()等方法。
最后,我們希望以異步的方式去執行請求,所以我們調用的是call.enqueue,將call加入調度隊列,然后等待任務執行完成,我們在Callback中即可得到結果。
onResponse回調的參數是response,一般情況下,比如我們希望獲得返回的字符串,可以通過
response.body().string()
獲取;如果希望獲得返回的二進制字節數組,則調用response.body().bytes();
如果你想拿到返回的inputStream,則調用response.body().byteStream()
一般的post請求
1) POST提交鍵值對
很多時候我們會需要通過POST方式把鍵值對數據傳送到服務器。 OkHttp提供了很方便的方式來做這件事情。比如提交用戶名和密碼用來登錄
post提交鍵值對其實和get方法之多了一個RequestBody,用來添加鍵值對
get提交連接如下
http://192.168.56.1:8080/LoginServlet?username=abc&password=123
post提交連接如下
OkHttpClient client = new OkHttpClient();
RequestBody requestBody=new FormBody.Builder()
.add("username","abc")
.add("password","123")
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Response response = client.newCall(request).execute();
String string = response.body().string();
System.out.println(string);
}
是不是比hc簡單多了,這里需要注意到一點是最新版的okhttp,原來的FormEncodingBuilder被FormBody代替了
POST提交Json數據
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
下載文件
new Thread(){public void run(){
OkHttpClient client = new OkHttpClient();
Request request=new Request.Builder().url("http://192.168.56.1:8080/tomcat.png").build();
try {
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("下載失敗");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream in=response.body().byteStream();
FileOutputStream fos=new FileOutputStream(new File(getFilesDir(),"11.png"));
int len=0;
byte []bytes=new byte[1024];
while ((len=in.read(bytes))!=-1){
fos.write(bytes,0,len);
}
fos.flush();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}}.start();
其實仔細看還是和上面的get請求差不多,無非就是get下載了,這里就只是改變了
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 {
//連接成功
}
上傳文件
public static void doFile(String url, String pathName, String fileName, Callback callback) {
//判斷文件類型
MediaType MEDIA_TYPE = MediaType.parse(judgeType(pathName));
//創建文件參數
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(MEDIA_TYPE.type(), fileName,
RequestBody.create(MEDIA_TYPE, new File(pathName)));
//發出請求參數
Request request = new Request.Builder()
.header("Authorization", "Client-ID " + "9199fdef135c122")
.url(url)
.post(builder.build())
.build();
Call call = getInstance().newCall(request);
call.enqueue(callback);
}
/**
* 根據文件路徑判斷MediaType
*
* @param path
* @return
*/
private static String judgeType(String path) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentTypeFor = fileNameMap.getContentTypeFor(path);
if (contentTypeFor == null) {
contentTypeFor = "application/octet-stream";
}
return contentTypeFor;
}