博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android网络(4):HttpClient必经之路----使用线程安全的单例模式HttpClient,及HttpClient和Application的融合...
阅读量:6212 次
发布时间:2019-06-21

本文共 5835 字,大约阅读时间需要 19 分钟。

简介了HttpClient和Tomcatserver的交互,主角是HttpClient,然后它跟server交互有两种方式即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));			//使用线程安全的连接管理来创建HttpClient			ClientConnectionManager 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;	@Override	public void onCreate() {		// TODO Auto-generated method stub		super.onCreate();		mHttpClient = this.createHttpClient();	}	@Override	public void onTerminate() {		// TODO Auto-generated method stub		super.onTerminate();		this.shutdownHttpClient();	}	@Override	public void onLowMemory() {		// TODO Auto-generated method stub		super.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));		//使用线程安全的连接管理来创建HttpClient		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;	}}
然后再AndroidManifest.xml理加入:

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

然后再Activity里,通过mMyApplication = (MyApplication)getApplication();

mMyApplication.getHttpClient()得到HttpClient就能够使用了。

能够看到在Application的onCreate里就实例化了HttpClient,且在低内存和关闭时关闭连接管理器,释放资源,比2中的写到一个普通文件中更优。

转载地址:http://zjsja.baihongyu.com/

你可能感兴趣的文章
stixel-world跑在kitti数据集
查看>>
pycharm+PyQt5+python最新开发环境配置
查看>>
keepalived VS zookeeper
查看>>
类锁与对象锁,重入锁
查看>>
StratifiedShuffleSplit 交叉验证
查看>>
MySQL时间增加、字符串拼接
查看>>
***ThinkPHP中的常用方法汇总总结:M方法,D方法,U方法,I方法
查看>>
vue当前路由跳转初步研究
查看>>
[MicroPython]TurniBit开发板DIY自动窗帘模拟系统
查看>>
lerna基本试用
查看>>
python3 如何给装饰器传递参数
查看>>
scala函数返回值
查看>>
设计模式1-单例模式(Singletion)
查看>>
JFinal提示:java.lang.RuntimeException: dao 只允许调用查询方法
查看>>
浮点数正则表达式
查看>>
Creator开源游戏、插件、教程、视频汇总
查看>>
zxing的使用及优化
查看>>
PHP笔试题(11道题)详解
查看>>
2018第34周六
查看>>
mybatis-plus忽略映射字段
查看>>