Android使用http協議與伺服器通訊

來源:互聯網
上載者:User

標籤:

網上介紹Android上http通訊的文章很多,不過大部分只給出了實現代碼的片段,一些注意事項和如何設計一個合理的類用來處理所有的http請求以及返回結果,一般都不會提及。因此,自己對此做了些總結,給出了我的一個解決方案。

首先,需要明確一下http通訊流程,Android目前提供兩種http通訊方式,HttpURLConnection和HttpClient,HttpURLConnection多用於發送或接收流式資料,因此比較適合上傳/下載檔案,HttpClient相對來講更大更全能,但是速度相對也要慢一點。在此只介紹HttpClient的通訊流程:

1.建立HttpClient對象,改對象可以用來多次發送不同的http請求

2.建立HttpPost或HttpGet對象,設定參數,每發送一次http請求,都需要這樣一個對象

3.利用HttpClient的execute方法發送請求並等待結果,該方法會一直阻塞當前線程,直到返回結果或拋出異常。

4.針對結果和異常做相應處理

 

根據上述流程,發現在設計類的時候,有幾點需要考慮到:

1.HttpClient對象可以重複使用,因此可以作為類的靜態變數

2.HttpPost/HttpGet對象一般無法重複使用(如果你每次請求的參數都差不多,也可以重複使用),因此可以建立一個方法用來初始化,同時設定一些需要上傳到伺服器的資源

3.目前Android不再支援在UI線程中發起Http請求,實際上也不該這麼做,因為這樣會阻塞UI線程。因此還需要一個子線程,用來發起Http請求,即執行execute方法

4.不同的請求對應不同的返回結果,對於如何處理返回結果(一般來說都是解析json&更新UI),需要有一定的自由度。

5.最簡單的方法是,每次需要發送http請求時,開一個子線程用於發送請求,子線程中接收到結果或拋出異常時,根據情況給UI線程發送message,最後在UI線程的handler的handleMessage方法中做結果解析和UI更新。這麼寫雖然簡單,但是UI線程和Http請求的耦合度很高,而且代碼比較散亂、醜陋。

 

基於上述幾點原因,我設計了一個PostRequest類,用於滿足我的http通訊需求。我只用到了Post請求,如果你需要Get請求,也可以改寫成GetRequest

package com.handspeaker.network;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.net.URI;import java.net.URISyntaxException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import org.apache.http.HttpResponse;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.params.HttpConnectionParams;import org.apache.http.params.HttpParams;import org.apache.http.protocol.HTTP;import org.apache.http.util.EntityUtils;import org.json.JSONObject;import android.app.Activity;import android.content.Context;import android.net.ConnectivityManager;import android.os.Handler;import android.util.Log;/** *  * 用於封裝&簡化http通訊 *  */public class PostRequest implements Runnable {        private static final int NO_SERVER_ERROR=1000;    //伺服器位址    public static final String URL = "fill your own url";    //一些請求類型    public final static String ADD = "/add";    public final static String UPDATE = "/update";    public final static String PING = "/ping";    //一些參數    private static int connectionTimeout = 60000;    private static int socketTimeout = 60000;    //類靜態變數    private static HttpClient httpClient=new DefaultHttpClient();    private static ExecutorService executorService=Executors.newCachedThreadPool();    private static Handler handler = new Handler();    //變數    private String strResult;    private HttpPost httpPost;    private HttpResponse httpResponse;    private OnReceiveDataListener onReceiveDataListener;    private int statusCode;    /**     * 建構函式,初始化一些可以重複使用的變數     */    public PostRequest() {        strResult = null;        httpResponse = null;        httpPost = new HttpPost();    }        /**     * 註冊接收資料監聽器     * @param listener     */    public void setOnReceiveDataListener(OnReceiveDataListener listener) {        onReceiveDataListener = listener;    }    /**     * 根據不同的請求類型來初始化httppost     *      * @param requestType     *            請求類型     * @param nameValuePairs     *            需要傳遞的參數     */    public void iniRequest(String requestType, JSONObject jsonObject) {        httpPost.addHeader("Content-Type", "text/json");        httpPost.addHeader("charset", "UTF-8");        httpPost.addHeader("Cache-Control", "no-cache");        HttpParams httpParameters = httpPost.getParams();        HttpConnectionParams.setConnectionTimeout(httpParameters,                connectionTimeout);        HttpConnectionParams.setSoTimeout(httpParameters, socketTimeout);        httpPost.setParams(httpParameters);        try {            httpPost.setURI(new URI(URL + requestType));            httpPost.setEntity(new StringEntity(jsonObject.toString(),                    HTTP.UTF_8));        } catch (URISyntaxException e1) {            e1.printStackTrace();        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }    }    /**     * 新開一個線程發送http請求     */    public void execute() {        executorService.execute(this);    }    /**     * 檢測網路狀況     *      * @return true is available else false     */    public static boolean checkNetState(Activity activity) {        ConnectivityManager connManager = (ConnectivityManager) activity                .getSystemService(Context.CONNECTIVITY_SERVICE);        if (connManager.getActiveNetworkInfo() != null) {            return connManager.getActiveNetworkInfo().isAvailable();        }        return false;    }    /**     * 發送http請求的具體執行代碼     */    @Override    public void run() {        httpResponse = null;        try {            httpResponse = httpClient.execute(httpPost);            strResult = EntityUtils.toString(httpResponse.getEntity());        } catch (ClientProtocolException e1) {            strResult = null;            e1.printStackTrace();        } catch (IOException e1) {            strResult = null;            e1.printStackTrace();        } finally {            if (httpResponse != null) {                statusCode = httpResponse.getStatusLine().getStatusCode();            }            else            {                statusCode=NO_SERVER_ERROR;            }            if(onReceiveDataListener!=null)            {                //將註冊的監聽器的onReceiveData方法加入到訊息佇列中去執行                handler.post(new Runnable() {                    @Override                    public void run() {                        onReceiveDataListener.onReceiveData(strResult, statusCode);                    }                });            }        }    }    /**     * 用於接收並處理http請求結果的監聽器     *     */    public interface OnReceiveDataListener {        /**         * the callback function for receiving the result data         * from post request, and further processing will be done here         * @param strResult the result in string style.         * @param StatusCode the status of the post         */        public abstract void onReceiveData(String strResult,int StatusCode);    }}

 

代碼使用了觀察者模式,任何需要接收http請求結果的類,都要實現OnReceiveDataListener介面的抽象方法,同時PostRequest執行個體調用setOnReceiveDataListener方法,註冊該監聽器。完整調用步驟如下:

1.建立PostRequest對象,實現onReceiveData介面,編寫自己的onReceiveData方法

2.註冊監聽器

3.調用PostRequest的iniRequest方法,初始化本次request

4.調用PostRequest的execute方法

 

可能的改進:

1.如果需要多個觀察者,可以把只能註冊單個監聽器改為可以註冊多個監聽器,維護一個監聽器List。

2.如果需求比較簡單,並希望調用流程更簡潔,iniRequest和execute可以合并

 

如果有更好的方法或者問題,歡迎隨時交流

 

轉:http://www.cnblogs.com/hrlnw/p/4118480.html

Android使用http協議與伺服器通訊

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.