Android 網路程式設計(三) 淺談HttpURLConnection
引言
上一篇文章我們簡單的分析了HTTP 的協議,理解了HTTP協議的基本構成。在Android 6.0以前,Android 原生的HTTP請求方式有兩種,HttpClient和HttpURLConnection。但因為HttpClient 的API比較複雜並且維護起來比較繁瑣,Android 團隊在6.0以後的版本便移除了HttpClient 的支援。而HttpUrlConnection由於其API 簡單並且體積小便於維護,便成為了官方推薦的網路請求方式,我們這篇文章也主要講述下HttpUrlConnection。
HttpUrlConnection 的使用
使用HttpUrlConnection 來進行網路請求大體上可以分為4個步驟:
- 獲取到HttpURLConnection 物件
- 進行全域性的網路設定並建立Http連線
- 進行資料處理
- 關閉連線
獲取到HttpURLConnection 物件
使用URL 物件的openConnection()方法獲取到HttpURLConnection 物件,這個物件是我們進行網路請求的核心。 網路請求在響應時間上有很大的不確定性,如果將網路請求放在主執行緒中執行,過長的耗時操作會阻塞主執行緒,導致程式卡死。因此,網路請求都應該放在子執行緒中執行。 示例程式碼如下
Url url = new URL("http://www.xianleshen:8080/springmvc/MyServlet/data?name=謙行&age=23" );
connection = (HttpURLConnection) url.openConnection();
進行全域性的網路設定並建立Http連線
獲取到HttpURLConnection物件後,要進行一些網路設定,比如說設定網路請求方式,連線超時時間,讀取超時時間,設定要傳送的資料等。如以下程式碼所示:
// HttpURLConnection預設就是用GET傳送請求,這裡要傳送資料,使用POST
connection.setRequestMethod("POST");
//設定連線超時時間
conn.setConnectTimeout(8000);
//設定讀取超時時間
conn.setReadTimeout (8000);
// URL 連線可用於輸入。如果打算使用 URL 連線進行輸入,則將 DoInput 標誌設定為 true;如果不打算使用,則設定為 false。預設值為 true
connection.setDoInput(true);
// URL 連線可用於輸出。如果打算使用 URL 連線進行輸出,則將 DoOutput 標誌設定為 true;如果不打算使用,則設定為 false。預設值為 false。
connection.setDoOutput(true);
// 獲取conn的輸出流
OutputStream out = connection.getOutputStream();
//給這個輸出流新增一個處理流,方便操作
DataOutputStream dos = new DataOutputStream(out);
//使用 writeBytes() 方法將資料提交到伺服器
dos.writeBytes("username=admin&password=123456");
// 建立連線
connection.connect();
從伺服器讀取資料並進行資料處理
通過呼叫 HttpUrlConnection 物件的一些方法可以獲取到伺服器傳送給客戶端的相應資訊,如狀態碼、響應內容長度、包含了響應內容的輸入流等等。如以下示例程式碼:
//獲取響應狀態碼,如 200 表示成功等
int responseCode = connection.getResponseCode();
//獲取包含響應內容的輸入流
InputStream in = connection.getInputStream();
//獲取響應內容長度
int contentLength = connection.getContentLength();
在獲取輸入流之後,就可以利用 Java 中的 IO 流的知識對該輸入流進行流處理,從而得到我們想要的資料。
關閉連線
在我們完成了所有資料寫入和讀取的流操作後,應該呼叫 disconnect() 方法關閉 Http 連線。
//關閉 Http 連線
connection.disconnect();
UrlHttpUtils
推薦給大家一個最簡單的HttpURLconnection封裝——UrlHttpUtils,只有五個Java檔案,可以直接將java 檔案拷到工程中使用。CallBack方法執行在UI執行緒。支援get請求,post請求,支援檔案上傳和下載。建議大家在有時間看看原始碼,這樣才能靈活的使用這些封裝的方法。
封裝的功能
- 一般的get請求
- 一般的post請求
- 上傳單個檔案(包含進度)
- 上傳list集合檔案
- 上傳map集合檔案
- 檔案下載(包含進度)
- 圖片下載(實現了圖片的壓縮)
使用示例
GET請求
String url = "https://www.baidu.com/";
UrlHttpUtil.get(url, new CallBackUtil.CallBackString() {
@Override
public void onFailure(int code, String errorMessage) {
}
@Override
public void onResponse(String response) {
}
});
POST請求
String url = "https://www.baidu.com/";
HashMap<String, String> paramsMap = new HashMap<>();
paramsMap.put("title","title");
UrlHttpUtil.post(url, paramsMap, new CallBackUtil.CallBackString() {
@Override
public void onFailure(int code, String errorMessage) {
}
@Override
public void onResponse(String response) {
}
});
上傳檔案
File file = new File(Environment.getExternalStorageDirectory()+"/kwwl/abc.jpg");
HashMap<String, String> paramsMap = new HashMap<>();
paramsMap.put("title","title");
UrlHttpUtil.uploadFile("url", file, "image",UrlHttpUtil.FILE_TYPE_FILE, paramsMap, new CallBackUtil.CallBackString() {
@Override
public void onFailure(int code, String errorMessage) {
}
@Override
public void onResponse(String response) {
}
});
下載檔案
UrlHttpUtil.downloadFile("url", new CallBackUtil.CallBackFile("fileDir","fileName") {
@Override
public void onFailure(int code, String errorMessage) {
}
@Override
public void onProgress(float progress, long total) {
super.onProgress(progress, total);
}
@Override
public void onResponse(File response) {
}
});