android 網絡編程之HttpURLConnection與HttpClient使用與封裝

博客逐步遷移至 極客兔兔的小站javascript

1.寫在前面

    大部分andriod應用須要與服務器進行數據交互,HTTP、FTP、SMTP或者是直接基於SOCKET編程均可以進行數據交互,可是HTTP必然是使用最普遍的協議。
    本文並不針對HTTP協議的具體內容,僅探討android開發中使用HTTP協議訪問網絡的兩種方式——HttpURLConnectionHttpClient
    由於須要訪問網絡,需在AndroidManifest.xml中添加以下權限html

<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;

// 如下代碼實現了以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();
}

2.2 POST方式

import java.io.DataOutputStream;

//將對應部分改成
connection.setRequestMethod("POST");
DataOutputStream data = new DataOutputStream(connection.getOutputStream());
data.writeBytes("stu_no=12345&stu_name=Tom");
  • 傳入多個參數用 & 隔開
  • 如需傳入複雜的參數,可以使用JSON,關於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;

// 建立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"); 
}

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.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方式一致

3.3 android 6.0移除HttpClient

  • android 6.0(API 23)版本的SDK已將Apache HttpClient相關類移除,解決辦法自行GOOGLE,推薦使用HTTPURLConnection。
  • 若還需使用該類,點擊查看解決辦法

4.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

4.1 定義接口HttpCallbackListener,爲了實現回調

// 定義HttpCallbackListener接口
// 包含兩個方法,成功和失敗的回調函數定義
public interface HttpCallbackListener {
    void onFinish(String response);
    void onError(Exception e);
}

4.2 建立HttpTool類,抽象請求方法(GET)

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();
    }
}

4.3 調用示例

//使用該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) {   
        // ...省略請求失敗的處理代碼
    } 
});

4.4 抽象請求方法(POST)

/* 在GET方法實現的基礎上增長一個參數params便可,
 * 將參數轉換爲字符串後傳入
 * 也能夠傳入鍵值對集合,再處理 */
public static void sendRequest(final String address,
    final String params, final HttpCallbackListener listener){
        //...
}
相關文章
相關標籤/搜索