Android中HttpURLConnection與HttpClient的使用與封裝
1.寫在前面
大部分andriod應(yīng)用需要與服務(wù)器進(jìn)行數(shù)據(jù)交互,HTTP、FTP、SMTP或者是直接基于SOCKET編程都可以進(jìn)行數(shù)據(jù)交互,但是HTTP必然是使用最廣泛的協(xié)議。
本文并不針對HTTP協(xié)議的具體內(nèi)容,僅探討android開發(fā)中使用HTTP協(xié)議訪問網(wǎng)絡(luò)的兩種方式——HttpURLConnection和HttpClient
因為需要訪問網(wǎng)絡(luò),需在AndroidManifest.xml中添加如下權(quán)限
<uses-permission android:name="android.permission.INTERNET" />
2.HttpURLConnection
2.1 GET方式
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; // 以下代碼實現(xiàn)了以GET方式發(fā)起HTTP請求 // 連接網(wǎng)絡(luò)是耗時操作,一般新建線程進(jìn)行 private void connectWithHttpURLConnection() { new Thread( new Runnable() { @Override public void run() { HttpURLConnection connection = null; try { // 調(diào)用URL對象的openConnection方法獲取HttpURLConnection的實例 URL url = new URL("http://www.dbjr.com.cn"); connection = (HttpURLConnection) url.openConnection(); // 設(shè)置請求方式,GET或POST connection.setRequestMethod("GET"); // 設(shè)置連接超時、讀取超時的時間,單位為毫秒(ms) connection.setConnectTimeout(8000); connection.setReadTimeout(8000); // getInputStream方法獲取服務(wù)器返回的輸入流 InputStream in = connection.getInputStream(); // 使用BufferedReader對象讀取返回的數(shù)據(jù)流 // 按行讀取,存儲在StringBuider對象response中 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } //.......... // 此處省略處理數(shù)據(jù)的代碼 // 若需要更新UI,需將數(shù)據(jù)傳回主線程,具體可搜索android多線程編程 } catch (Exception e){ e.printStackTrace(); } finally { if (connection != null){ // 結(jié)束后,關(guān)閉連接 connection.disconnect(); } } } }).start(); }
2.2 POST方式
import java.io.DataOutputStream; //將對應(yīng)部分改為 connection.setRequestMethod("POST"); DataOutputStream data = new DataOutputStream(connection.getOutputStream()); data.writeBytes("stu_no=12345&stu_name=Tom");
傳入多個參數(shù)用&隔開
如需傳入復(fù)雜的參數(shù),可使用JSON,關(guān)于JSON的用法介紹,可以參考我的另一篇隨筆JSON解析的兩種方法。
3.HttpClient
3.1 GET方式
import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.HttpResponse; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; // 創(chuàng)建DefaultHttpClient實例 HttpClient httpClient = new DefaultHttpClient(); //傳入網(wǎng)址,然后執(zhí)行 HttpGet httpGet = new HttpGet("http://www.dbjr.com.cn"); HttpResponse httpResponse = httpClient.execute(httpGet); // 由狀態(tài)碼判斷請求結(jié)果, // 常見狀態(tài)碼 200 請求成功,404 頁面未找到 // 關(guān)于HTTP的更多狀態(tài)碼直接GOOGLE if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // 請求成功,使用HttpEntity獲得返回數(shù)據(jù) // 使用EntityUtils將返回數(shù)據(jù)轉(zhuǎn)換為字符串 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity); //如果是中文,指定編碼 //==>String response = EntityUtils.toString(entity, "utf-8"); }
3.2 POST方式
import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.message.BasicNameValuePair; HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost("http://www.dbjr.com.cn"); // 使用NameValuePair(鍵值對)存放參數(shù) List<NameValuePair> data = new ArrayList<NameValuePair>(); // 添加鍵值對 data.add(new BasicNameValuePair("stu_no", 12345)); data.add(new BasicNameValuePair("stu_name", "Tom")); // 使用setEntity方法傳入編碼后的參數(shù) httpPost.setEntity(new UrlEncodedFormEntity(data, "utf-8")); // 執(zhí)行該POST請求 HttpResponse httpResponse = httpClient.execute(httpPost); // .....省略處理httpResponse的代碼,與GET方式一致
3.3 android 6.0移除HttpClient
android 6.0(API 23)版本的SDK已將Apache HttpClient相關(guān)類移除,解決辦法自行GOOGLE,推薦使用HTTPURLConnection。
若還需使用該類,點擊查看解決辦法。
4.HttpURLConnection實戰(zhàn)
如果你使用過JQuery(一個javasript庫),你一定對JQuery的網(wǎng)路編程印象深刻,比如一個HTTP請求只需以下幾行代碼。
// JQuery的post方法 $.post("http://www.dbjr.com.cn",{ "stu_no":12345, "stu_name":"Tom", }).done(function(){ //...請求成功的代碼 }).fail(function(){ //...請求失敗的代碼 }).always(function(){ //...總會執(zhí)行的代碼 })
我們當(dāng)然不希望每次網(wǎng)絡(luò)請求都寫下2.1中那么繁瑣的代碼,那么android的HTTP請求能否像JQuery那么簡單呢?當(dāng)然可以!下面的代碼實現(xiàn)了HttpURLConnection的HTTP請求方法封裝:
4.1 定義接口HttpCallbackListener,為了實現(xiàn)回調(diào)
// 定義HttpCallbackListener接口 // 包含兩個方法,成功和失敗的回調(diào)函數(shù)定義 public interface HttpCallbackListener { void onFinish(String response); void onError(Exception e); }
4.2 創(chuàng)建HttpTool類,抽象請求方法(GET)
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; /* 創(chuàng)建一個新的類 HttpTool,將公共的操作抽象出來 * 為了避免調(diào)用sendRequest方法時需實例化,設(shè)置為靜態(tài)方法 * 傳入HttpCallbackListener對象為了方法回調(diào) * 因為網(wǎng)絡(luò)請求比較耗時,一般在子線程中進(jìn)行, * 為了獲得服務(wù)器返回的數(shù)據(jù),需要使用java的回調(diào)機制 */ public class HttpTool { public static void sendRequest(final String address, final HttpCallbackListener listener) { new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; try { URL url = new URL(address); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } if (listener != null) { // 回調(diào)方法 onFinish() listener.onFinish(response.toString()); } } catch (Exception e) { if (listener != null) { // 回調(diào)方法 onError() listener.onError(e); } } finally { if (connection != null) { connection.disconnect(); } } } }).start(); } }
4.3 調(diào)用示例
//使用該HttpTool發(fā)起GET請求 String url = "http://www.dbjr.com.cn"; HttpTool.sendRequest(url,new HttpCallbackListener(){ @Override public void onFinish(String response) { // ...省略對返回結(jié)果的處理代碼 } @Override public void onError(Exception e) { // ...省略請求失敗的處理代碼 } });
4.4 抽象請求方法(POST)
/* 在GET方法實現(xiàn)的基礎(chǔ)上增加一個參數(shù)params即可, * 將參數(shù)轉(zhuǎn)換為字符串后傳入 * 也可以傳入鍵值對集合,再處理 */ public static void sendRequest(final String address, final String params, final HttpCallbackListener listener){ //... }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
Android 5.0+ 屏幕錄制實現(xiàn)的示例代碼
這篇文章主要介紹了Android 5.0+ 屏幕錄制實現(xiàn)的示例代碼,從 5.0 開始,系統(tǒng)提供給了 app 錄制屏幕的一系列方法,不需要 root 權(quán)限,只需要用戶授權(quán)即可錄屏,相對來說較為簡單,感興趣的小伙伴們可以參考一下2018-05-05Android開發(fā)中調(diào)用系統(tǒng)相冊上傳圖片到服務(wù)器OPPO等部分手機上出現(xiàn)短暫的顯示桌面問題的解決方法
這篇文章主要介紹了Android開發(fā)中調(diào)用系統(tǒng)相冊上傳圖片到服務(wù)器OPPO等部分手機上出現(xiàn)短暫的顯示桌面問題的解決方法,需要的朋友可以參考下2016-12-12Android OkHttp Post上傳文件并且攜帶參數(shù)實例詳解
這篇文章主要介紹了Android OkHttp Post上傳文件并且攜帶參數(shù)實例詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03Android ListView長按彈出菜單二種實現(xiàn)方式示例
這篇文章主要介紹了Android ListView長按彈出菜單的方法,大家參考實現(xiàn)2013-11-11Android的HTTP擴展包OkHttp中的緩存功能使用方法解析
OkHttp(GitHub主頁https://github.com/square/okhttp)是一款高人氣的第三方Android網(wǎng)絡(luò)編程包,這里我們來看一下Android的HTTP擴展包OkHttp中的緩存功能使用方法解析:2016-07-07解決Android 6.0獲取wifi Mac地址為02:00:00:00:00:00問題
這篇文章主要介紹了Android 6.0獲取wifi Mac地址為02:00:00:00:00:00的解決方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-11-11Android App中各種數(shù)據(jù)保存方式的使用實例總結(jié)
這篇文章主要介紹了Android App中各種數(shù)據(jù)保存方式的使用實例,列舉了SharedPreferences接口、機身空間存儲、SD卡存儲和SQLite數(shù)據(jù)庫四種方式的代碼例子,需要的朋友可以參考下2016-04-04