博客逐步遷移至 極客兔兔的小站javascript
大部分andriod應用須要與服務器進行數據交互,HTTP、FTP、SMTP或者是直接基於SOCKET編程均可以進行數據交互,可是HTTP必然是使用最普遍的協議。
本文並不針對HTTP協議的具體內容,僅探討android開發中使用HTTP協議訪問網絡的兩種方式——HttpURLConnection
和HttpClient
由於須要訪問網絡,需在AndroidManifest.xml中添加以下權限html
<uses-permission android:name="android.permission.INTERNET" />
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; // 如下代碼實現了以GET方式發起HTTP請求 // 鏈接網絡是耗時操做,通常新建線程進行 private void connectWithHttpURLConnection() { new Thread( new Runnable() { @Override public void run() { HttpURLConnection connection = null; try { // 調用URL對象的openConnection方法獲取HttpURLConnection的實例 URL url = new URL("http://www.cnblogs.com/gzdaijie"); connection = (HttpURLConnection) url.openConnection(); // 設置請求方式,GET或POST connection.setRequestMethod("GET"); // 設置鏈接超時、讀取超時的時間,單位爲毫秒(ms) connection.setConnectTimeout(8000); connection.setReadTimeout(8000); // getInputStream方法獲取服務器返回的輸入流 InputStream in = connection.getInputStream(); // 使用BufferedReader對象讀取返回的數據流 // 按行讀取,存儲在StringBuider對象response中 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } //.......... // 此處省略處理數據的代碼 // 若須要更新UI,需將數據傳回主線程,具體可搜索android多線程編程 } catch (Exception e){ e.printStackTrace(); } finally { if (connection != null){ // 結束後,關閉鏈接 connection.disconnect(); } } } }).start(); }
import java.io.DataOutputStream; //將對應部分改成 connection.setRequestMethod("POST"); DataOutputStream data = new DataOutputStream(connection.getOutputStream()); data.writeBytes("stu_no=12345&stu_name=Tom");
- 傳入多個參數用 & 隔開
- 如需傳入複雜的參數,可以使用JSON,關於
JSON的用法介紹
,能夠參考個人另外一篇隨筆JSON解析的兩種方法。
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; // 建立DefaultHttpClient實例 HttpClient httpClient = new DefaultHttpClient(); //傳入網址,而後執行 HttpGet httpGet = new HttpGet("http://www.cnblogs.com/gzdaijie"); HttpResponse httpResponse = httpClient.execute(httpGet); // 由狀態碼判斷請求結果, // 常見狀態碼 200 請求成功,404 頁面未找到 // 關於HTTP的更多狀態碼直接GOOGLE if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // 請求成功,使用HttpEntity得到返回數據 // 使用EntityUtils將返回數據轉換爲字符串 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity); //若是是中文,指定編碼 //==>String response = EntityUtils.toString(entity, "utf-8"); }
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.cnblogs.com/gzdaijie"); // 使用NameValuePair(鍵值對)存放參數 List<NameValuePair> data = new ArrayList<NameValuePair>(); // 添加鍵值對 data.add(new BasicNameValuePair("stu_no", 12345)); data.add(new BasicNameValuePair("stu_name", "Tom")); // 使用setEntity方法傳入編碼後的參數 httpPost.setEntity(new UrlEncodedFormEntity(data, "utf-8")); // 執行該POST請求 HttpResponse httpResponse = httpClient.execute(httpPost); // .....省略處理httpResponse的代碼,與GET方式一致
- android 6.0(API 23)版本的SDK已將Apache HttpClient相關類移除,解決辦法自行GOOGLE,推薦使用HTTPURLConnection。
- 若還需使用該類,點擊查看解決辦法。
若是你使用過JQuery
(一個javasript庫),你必定對JQuery的網路編程印象深入,好比一個HTTP請求只需如下幾行代碼。java
// JQuery的post方法 $.post("http://www.cnblogs.com/gzdaijie",{ "stu_no":12345, "stu_name":"Tom", }).done(function(){ //...請求成功的代碼 }).fail(function(){ //...請求失敗的代碼 }).always(function(){ //...總會執行的代碼 })
咱們固然不但願每次網絡請求都寫下2.1中那麼繁瑣的代碼,那麼android的HTTP請求可否像JQuery那麼簡單呢?固然能夠!下面的代碼實現了HttpURLConnection的HTTP請求方法封裝
:android
// 定義HttpCallbackListener接口 // 包含兩個方法,成功和失敗的回調函數定義 public interface HttpCallbackListener { void onFinish(String response); void onError(Exception e); }
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; /* 建立一個新的類 HttpTool,將公共的操做抽象出來 * 爲了不調用sendRequest方法時需實例化,設置爲靜態方法 * 傳入HttpCallbackListener對象爲了方法回調 * 由於網絡請求比較耗時,通常在子線程中進行, * 爲了得到服務器返回的數據,須要使用java的回調機制 */ 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) { // 回調方法 onFinish() listener.onFinish(response.toString()); } } catch (Exception e) { if (listener != null) { // 回調方法 onError() listener.onError(e); } } finally { if (connection != null) { connection.disconnect(); } } } }).start(); } }
//使用該HttpTool發起GET請求 String url = "http://www.cnblogs.com/gzdaijie"; HttpTool.sendRequest(url,new HttpCallbackListener(){ @Override public void onFinish(String response) { // ...省略對返回結果的處理代碼 } @Override public void onError(Exception e) { // ...省略請求失敗的處理代碼 } });
/* 在GET方法實現的基礎上增長一個參數params便可, * 將參數轉換爲字符串後傳入 * 也能夠傳入鍵值對集合,再處理 */ public static void sendRequest(final String address, final String params, final HttpCallbackListener listener){ //... }