标签:android   style   blog   http   java   使用   os   io   
上文简 单介绍了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 来完成。下面贴出完整代码:
- <span style="font-family:Comic Sans MS;font-size:18px;">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;  
 
-     
 
-     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);  
 
-             
 
-             SchemeRegistry schReg = new SchemeRegistry();  
 
-             schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));  
 
-             schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));  
 
-             
 
-             ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);  
 
-             mHttpClient = new DefaultHttpClient(conMgr, params);  
 
-         }  
 
-         return mHttpClient;  
 
-     }  
 
-       
 
- }  
 
- </span>  
 
 
方法getSaveHttpClient()即可获得线程安全的单例httpClient,注释很详细了啥都不说了,可以直接使用。
3、已经很完美了,还能不能再优化呢? 
可以使用Application来进一步优化创建HttpClient的时机及其他配置。Application的相关知识参见:链接 
新建包名org.yanzi.application,在里面新建MyApplication.java,完整代码如下:
- <span style="font-family:Comic Sans MS;font-size:18px;">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;  
 
-     @Override  
 
-     public void onCreate() {  
 
-         
 
-         super.onCreate();  
 
-         mHttpClient = this.createHttpClient();  
 
-     }  
 
-   
 
-     @Override  
 
-     public void onTerminate() {  
 
-         
 
-         super.onTerminate();  
 
-         this.shutdownHttpClient();  
 
-     }  
 
-   
 
-     @Override  
 
-     public void onLowMemory() {  
 
-         
 
-         super.onLowMemory();  
 
-         this.shutdownHttpClient();  
 
-     }  
 
-       
 
-     
 
-     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);  
 
-         
 
-         SchemeRegistry schReg = new SchemeRegistry();  
 
-         schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));  
 
-         schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));  
 
-         
 
-         ClientConnectionManager 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;  
 
-     }  
 
-   
 
- }  
 
- </span>  
 
 
然后再AndroidManifest.xml理添加:
android:name="org.yanzi.application.MyApplication"
- <span style="font-family:Comic Sans MS;font-size:18px;">    <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></span>  
 
 
然后再Activity里,通过mMyApplication = (MyApplication)getApplication();
mMyApplication.getHttpClient()得到HttpClient就可以使用了。
可以看到在Application的onCreate里就实例化了HttpClient,且在低内存和关闭时关闭连接管理器,释放资源,比2中的写到一个普通文件里更优。
ndroid网络(4):HttpClient必经之路----使用线程安全的单例模式HttpClient,及HttpClient和Application的融合,布布扣,bubuko.com
ndroid网络(4):HttpClient必经之路----使用线程安全的单例模式HttpClient,及HttpClient和Application的融合
标签:android   style   blog   http   java   使用   os   io   
原文地址:http://www.cnblogs.com/Free-Thinker/p/3910811.html