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
因?yàn)樾枰L問網(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;
// 以下代碼實(shí)現(xiàn)了以GET方式發(fā)起HTTP請求
// 連接網(wǎng)絡(luò)是耗時(shí)操作,一般新建線程進(jìn)行
private void connectWithHttpURLConnection() {
new Thread( new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try {
// 調(diào)用URL對象的openConnection方法獲取HttpURLConnection的實(shí)例
URL url = new URL("http://www.dhdzp.com");
connection = (HttpURLConnection) url.openConnection();
// 設(shè)置請求方式,GET或POST
connection.setRequestMethod("GET");
// 設(shè)置連接超時(shí)、讀取超時(shí)的時(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");
傳入多個(gè)參數(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實(shí)例
HttpClient httpClient = new DefaultHttpClient();
//傳入網(wǎng)址,然后執(zhí)行
HttpGet httpGet = new HttpGet("http://www.dhdzp.com");
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獲得返回?cái)?shù)據(jù)
// 使用EntityUtils將返回?cái)?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.dhdzp.com");
// 使用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í)行該P(yáng)OST請求
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。
若還需使用該類,點(diǎn)擊查看解決辦法。
4.HttpURLConnection實(shí)戰(zhàn)
如果你使用過JQuery(一個(gè)javasript庫),你一定對JQuery的網(wǎng)路編程印象深刻,比如一個(gè)HTTP請求只需以下幾行代碼。
// JQuery的post方法
$.post("http://www.dhdzp.com",{
"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)然可以!下面的代碼實(shí)現(xiàn)了HttpURLConnection的HTTP請求方法封裝:
4.1 定義接口HttpCallbackListener,為了實(shí)現(xiàn)回調(diào)
// 定義HttpCallbackListener接口
// 包含兩個(gè)方法,成功和失敗的回調(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)建一個(gè)新的類 HttpTool,將公共的操作抽象出來
* 為了避免調(diào)用sendRequest方法時(shí)需實(shí)例化,設(shè)置為靜態(tài)方法
* 傳入HttpCallbackListener對象為了方法回調(diào)
* 因?yàn)榫W(wǎng)絡(luò)請求比較耗時(shí),一般在子線程中進(jìn)行,
* 為了獲得服務(wù)器返回的數(shù)據(jù),需要使用java的回調(diào)機(jī)制 */
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.dhdzp.com";
HttpTool.sendRequest(url,new HttpCallbackListener(){
@Override
public void onFinish(String response) {
// ...省略對返回結(jié)果的處理代碼
}
@Override
public void onError(Exception e) {
// ...省略請求失敗的處理代碼
}
});
4.4 抽象請求方法(POST)
/* 在GET方法實(shí)現(xiàn)的基礎(chǔ)上增加一個(gè)參數(shù)params即可,
* 將參數(shù)轉(zhuǎn)換為字符串后傳入
* 也可以傳入鍵值對集合,再處理 */
public static void sendRequest(final String address,
final String params, final HttpCallbackListener listener){
//...
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
實(shí)例講解Android中ContentProvider組件的使用方法
這篇文章主要介紹了Android中ContentProvider組件的使用方法,包括ContentProvider使用單元測試的步驟,需要的朋友可以參考下2016-04-04
Android實(shí)現(xiàn)RecyclerView下拉刷新效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)RecyclerView下拉刷新效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Android ListView監(jiān)聽滑動事件的方法(詳解)
下面小編就為大家?guī)硪黄狝ndroid ListView監(jiān)聽滑動事件的方法(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03
淺談Android開發(fā)Webview的Loading使用效果
這篇文章主要為大家介紹了淺談Android開發(fā)Webview的Loading使用效果詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Android ViewPager實(shí)現(xiàn)圖片輪翻效果
這篇文章主要為大家詳細(xì)介紹了Android ViewPager實(shí)現(xiàn)圖片輪翻效果的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
Android開發(fā)實(shí)現(xiàn)的標(biāo)準(zhǔn)體重計(jì)算器功能示例
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)的標(biāo)準(zhǔn)體重計(jì)算器功能,結(jié)合實(shí)例形式分析了Android體重計(jì)算器的界面布局與功能實(shí)現(xiàn)相關(guān)操作技巧,需要的朋友可以參考下2017-12-12
Flutter實(shí)現(xiàn)資源下載斷點(diǎn)續(xù)傳的示例代碼
在項(xiàng)目開發(fā)中,特別是C端的產(chǎn)品,資源下載實(shí)現(xiàn)斷點(diǎn)續(xù)傳是非常有必要的。今天我們不講過多原理的知識,分享下簡單實(shí)用的資源斷點(diǎn)續(xù)傳2022-07-07

