Android網路(4):HttpClient必經之路----使用安全執行緒的單例模式HttpClient,及HttpClient和Application的融合

來源:互聯網
上載者:User

標籤:application   tomcat   android   httpclient   

上文簡單介紹了HttpClient和Tomcat伺服器的互動,主角是HttpClient,然後它跟伺服器互動有兩種方式即get和post。所以這個HttpClient就類似於電腦上用的瀏覽器。當我開啟多個網頁的時候,並不需要開一個網頁就開一個瀏覽器,而是一個瀏覽器上面開了好幾個網頁。對應於HttpClient,即無需串連一次就new一個HttpClient。一般,我們希望一個應用裡就一個HttpClient就ok了,就像我們的手機或PC,沒人會呼呼的裝好幾個瀏覽器。本文即解決此問題,代碼可以直接拿過去複用。

1、自然而然想到單例。

public class MyHttpClient {
private static HttpClient mHttpClient = null;
private static final String CHARSET = HTTP.UTF_8;
//將建構函式封掉,只能通過對外介面來擷取HttpClient執行個體
private MyHttpClient(){


}
public static HttpClient getHttpClient(){
if(mHttpClient == null){
mHttpClient = new DefaultHttpClient();
}
return mHttpClient;
}
}

上面是最簡單的一種單例,確實能夠滿足需要。但不能滿足多線程的要求,即當同時完成多個Http請求時,就出馬蛋了。

2、安全執行緒的HttpClient

幸運的是android已經提供了可以建立安全執行緒的HttpClient,即通過ClientConnectionManager 來完成。下面貼出完整代碼:

package org.yanzi.webutil;import org.apache.http.HttpVersion;import org.apache.http.client.HttpClient;import org.apache.http.conn.ClientConnectionManager;import org.apache.http.conn.params.ConnManagerParams;import org.apache.http.conn.scheme.PlainSocketFactory;import org.apache.http.conn.scheme.Scheme;import org.apache.http.conn.scheme.SchemeRegistry;import org.apache.http.conn.ssl.SSLSocketFactory;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;import org.apache.http.params.BasicHttpParams;import org.apache.http.params.HttpConnectionParams;import org.apache.http.params.HttpParams;import org.apache.http.params.HttpProtocolParams;import org.apache.http.protocol.HTTP;public class MyHttpClient {private static HttpClient mHttpClient = null;private static final String CHARSET = HTTP.UTF_8;//將建構函式封掉,只能通過對外介面來擷取HttpClient執行個體private MyHttpClient(){}public static HttpClient getHttpClient(){if(mHttpClient == null){mHttpClient = new DefaultHttpClient();}return mHttpClient;}public static synchronized HttpClient getSaveHttpClient(){if(mHttpClient == null){HttpParams params = new BasicHttpParams();//設定基本參數HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);HttpProtocolParams.setContentCharset(params, CHARSET);HttpProtocolParams.setUseExpectContinue(params, true);//逾時設定/*從串連池中取串連的逾時時間*/ConnManagerParams.setTimeout(params, 1000);/*連線逾時*/HttpConnectionParams.setConnectionTimeout(params, 2000);/*請求逾時*/HttpConnectionParams.setSoTimeout(params, 4000);//設定HttpClient支援HTTp和HTTPS兩種模式SchemeRegistry schReg = new SchemeRegistry();schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));//使用安全執行緒的串連管理來建立HttpClientClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);mHttpClient = new DefaultHttpClient(conMgr, params);}return mHttpClient;}}

方法getSaveHttpClient()即可獲得安全執行緒的單例httpClient,注釋很詳細了啥都不說了,可以直接使用。

3、已經很完美了,還能不能再最佳化呢? 

可以使用Application來進一步最佳化建立HttpClient的時機及其他配置。Application的相關知識參見:連結 

建立包名org.yanzi.application,在裡面建立MyApplication.java,完整代碼如下:

package org.yanzi.application;import org.apache.http.HttpVersion;import org.apache.http.client.HttpClient;import org.apache.http.conn.ClientConnectionManager;import org.apache.http.conn.params.ConnManagerParams;import org.apache.http.conn.scheme.PlainSocketFactory;import org.apache.http.conn.scheme.Scheme;import org.apache.http.conn.scheme.SchemeRegistry;import org.apache.http.conn.ssl.SSLSocketFactory;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;import org.apache.http.params.BasicHttpParams;import org.apache.http.params.HttpConnectionParams;import org.apache.http.params.HttpParams;import org.apache.http.params.HttpProtocolParams;import org.apache.http.protocol.HTTP;import android.app.Application;public class MyApplication extends Application {private HttpClient mHttpClient = null;private static final String CHARSET = HTTP.UTF_8;@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();mHttpClient = this.createHttpClient();}@Overridepublic void onTerminate() {// TODO Auto-generated method stubsuper.onTerminate();this.shutdownHttpClient();}@Overridepublic void onLowMemory() {// TODO Auto-generated method stubsuper.onLowMemory();this.shutdownHttpClient();}/**建立HttpClient執行個體 * @return */private HttpClient createHttpClient(){HttpParams params = new BasicHttpParams();//設定基本參數HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);HttpProtocolParams.setContentCharset(params, CHARSET);HttpProtocolParams.setUseExpectContinue(params, true);//逾時設定/*從串連池中取串連的逾時時間*/ConnManagerParams.setTimeout(params, 1000);/*連線逾時*/HttpConnectionParams.setConnectionTimeout(params, 2000);/*請求逾時*/HttpConnectionParams.setSoTimeout(params, 4000);//設定HttpClient支援HTTp和HTTPS兩種模式SchemeRegistry schReg = new SchemeRegistry();schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));//使用安全執行緒的串連管理來建立HttpClientClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);HttpClient client = new DefaultHttpClient(conMgr, params);return client;}private void shutdownHttpClient(){if(mHttpClient != null && mHttpClient.getConnectionManager() != null){mHttpClient.getConnectionManager().shutdown();}}public HttpClient getHttpClient(){return mHttpClient;}}

然後再AndroidManifest.xml理添加:

android:name="org.yanzi.application.MyApplication"

    <application        android:name="org.yanzi.application.MyApplication"        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="org.yanzi.testtomecat.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>

然後再Activity裡,通過mMyApplication = (MyApplication)getApplication();

mMyApplication.getHttpClient()得到HttpClient就可以使用了。

可以看到在Application的onCreate裡就執行個體化了HttpClient,且在低記憶體和關閉時關閉連線管理員,釋放資源,比2中的寫到一個普通檔案裡更優。


相關文章

聯繫我們

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