【轉】 Pro Android學習筆記(七一):HTTP服務(5):多線程調用HttpClient

來源:互聯網
上載者:User

標籤:

目錄(?)[-]

  1. 應用共用HttpClient對象的同步問題
  2. 建立共用HttpClient代碼
    1. 建立共用對象
    2. 建立可共用的HttpClient對象
  3. 使用共用HttpClient對象的代碼
    1. 基礎代碼
    2. 修改HTTP串連的參數
  4. 使用共同的Appcliation對象

文章轉載只能用於非商業性質,且不能帶有虛擬貨幣、積分、註冊等附加條件,轉載須註明出處:http://blog.csdn.net/flowingflying/

應用共用HttpClient對象的同步問題

在之前的例子中,HttpClient只用於某個請求,我們可以為整個應用建立一個共用的HttpClient對象。這就存在多線程使用的問題,而HttpClient已經考慮這個問題,只需要建立一個使用ThreadSafeClientConnManager的DefaultHttpClient對象。

建立共用HttpClient代碼建立共用對象

建立共用對象的方式是通用,如下:

public class CustomHttpClient { 
    private static HttpClient client = null;  //應用共用的對象
     
    /* 採用private的構造器,禁止了其他類通過CustomHttpClient xx = new CustomHttpClient();這種方式建立對象,確保對象的唯一性 */
   private CustomHttpClient(){ 
    } 
    /* 通過靜態調用擷取對象,第一次調用為空白時進行建立 */ 
    public static synchronized HttpClient getCustomHttpClient(){
 
        if(client == null){ 
           /*如果對象為空白,建立之*/ 
            ... ... 
        } 
        return client; 
    } 
    /*禁止clone,同樣也是保證對象的唯一性*/ 
    public Object clone() throws CloneNotSupportedException{ 
        throw new CloneNotSupportedException(); 
    } 
    
}

建立可共用的HttpClient對象

下面給出上面代碼中省略的部分,當對象為空白是,建立HttpClient對象的代碼,為了方便理解,代碼從可以從後往前看。

//【2.1】設定Http參數 
HttpParams params = new BasicHttpParams();
 
/* 設定HttpParam是的基本參數,其實都是對應http請求的訊息頭。其中三個都很好理解,重點介紹一些setUserExpectContinue。 一般都設定為flase,設定為true通常是傳遞request訊息很大(例攜帶大檔案),而伺服器可能需要認證,我們不希望傳完這個大檔案,才收到伺服器的拒絕。HTTP是TCP流方式,當server收到請求的頭欄位是Except:100-continue, 不在等待整個請求,返回100 continue應答繼續讀取,或者給出拒絕請求(final Status code,如4xx)。 具體可以參考:http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3 */
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true); 
HttpProtocolParams.setUserAgent(params, "Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83)" +
     " AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"); 
/* 設定逾時時間。逾時的異常均屬於IOException,此外ClientProtocolException也是與IOException*/
// 從ClientConnectionManager擷取串連的時間,這是從串連池中擷取串連的逾時設定,只有在串連池所有串連都在使用的情況下才可能出現逾時。逾時會扔出ConnectionPoolTimeoutException。一個HttpClient對應管理器,有串連池,裡面有多個串連(socket),這是我對其架構的猜測。
ConnManagerParams.setTimeout(params, 1000); 
// 這是串連到遠端web server的逾時設定,逾時會扔出ConnectTimeoutException
HttpConnectionParams.setConnectionTimeout(params, 5000);//連線逾時
// 這是發送請求訊息後,最多等待多長時間得到響應的設定,逾時會扔出SocketTimeoutException
HttpConnectionParams.setSoTimeout(params, 10000);//socket逾時
//【2.2】設定Sheme,註冊了http和https 
SchemeRegistry schReg = new SchemeRegistry(); 
schReg.register(new Scheme("http",PlainSocketFactory.getSocketFactory(), 80)); 
schReg.register(new Scheme("https",PlainSocketFactory.getSocketFactory(), 443)); 

//【2】ClientConnectionManager用於管理HTTP串連,我們使用同一個client來處理請求,要確保多線程的使用安全,採用ThreadSafeClientConnManager,是安全執行緒的串連池。如果多個線程同時請求,或有延遲情況。
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params,schReg);
//【1】以ThreadSafeClientConnManager為管理器參數,建立可進行多線程調用的同步保護的HttpClient對象
client = new DefaultHttpClient(conMgr,params);
 

使用共用HttpClient對象的代碼基礎代碼

下面給出Activity調用這個共用的HttpClient的代碼:

public class HttpActivity extends Activity{ 
    private HttpClient client = null; 
    
    protected void onCreate(Bundle savedInstanceState) {  
         …… //UI處理等 
        client = CustomHttpClient.getCustomHttpClient();        
        getHttpContent(); 
    } 
    
    private void getHttpContent(){ 
        try{  
            HttpGet request = new HttpGet("http://www.google.com");            
            /* 在處理response時,利用Android提供的BasicResponseHandler:handleResponse(HttpResponse response),Returns the response body as a String. if the response was successful (a 2xx status code).  */       
            String page = client.execute(request,new BasicResponseHandler()); 
            Log.d("PRO-HTTP",page); 
        }catch(IOException e){ 
            e.printStackTrace();  
        } 
    } 

修改HTTP串連的參數

我們在建立HttpClient時已經設定了有關的HTTP串連參數,實際對應的是HTTP請求訊息中的訊息頭,如果某個請求需要對這些參數進行修改,不應對公用屬性進行修改,否則會影響到其他請求,而是通過對具體的request請求進行設定。代碼例子如下:

// 我們設定了內部網的一個空地址,通過LogCat中連線逾時出現的時間,來判斷參數修改是否成功
HttpGet request = new HttpGet("http://192.168.0.199");              

// 讀取httpClient的參數設定 
HttpParams clientParams=client.getParams(); 
Log.d("PRO-HTTP",Log.d(String.valueOf(HttpConnectionParams.getConnectionTimeout(clientParams)));//顯示為5000
Log.d("PRO-HTTP",String.valueOf(HttpConnectionParams.getSoTimeout(clientParams)));//顯示為10000  
             
// 原來設定的連線逾時是5秒,下面將重新設定該參數,設為20秒,我們將新的參數設定在request中,將不影響其他的請求
HttpParams params = request.getParams(); 
HttpConnectionParams.setConnectionTimeout(params, 20000);//20s 
request.setParams(params);  
Log.d("PRO-HTTP",String.valueOf(HttpConnectionParams.getConnectionTimeout(params)));//顯示20000
Log.d("PRO-HTTP",String.valueOf(HttpConnectionParams.getSoTimeout(params))); //顯示0

使用共同的Appcliation對象

對於應用全域共用同一對象,使人想起appclication對象,對於Android應用,都會有一個application對象,在在應用中可以通過getApplicationContext()或者getApplication()來獲得。如果我們沒有自訂的Application類,就是用android.app.Application。我們當然也可以將HttpClient對象放置在自訂的application類,但是為了這點小事來是Application類變得複雜並不可取。

在此,我們將探討自訂的Appcliation。很簡單,只要建立自訂的Application類即可,至於application對象的建立,均有系統來完成。下面我們在自訂的Application中加入一個計數器。

import android.app.Application; 

public class CustomApplication extends Application
    private int counter = 0; 
    
    public int getCounter(){ 
        return ++counter; 
    } 
}

在應用的所有組件都都可以application對象,且是唯一的一個。從運行結果看出,獲得這個對象有好幾種方式。

CustomApplication app = (CustomApplication)getApplication(); 
Log.d("PRO-wei","counter: " + app.getCounter());  //測試一下計數器是否正常
Log.d("PRO-wei","context: " + app); 
Log.d("PRO-wei","context: " + app.getApplicationContext());  //測試一下獲得app類的其他方式 
Log.d("PRO-wei","context: " + getApplicationContext());  //測試一下獲得app類的其他方式

本博文涉及的例子代碼,可以在Pro Android學習:Http service小例子中下載。

相關連結: 我的Android開發相關文章

【轉】 Pro Android學習筆記(七一):HTTP服務(5):多線程調用HttpClient

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.