使用runOnUiThread解决Handler无法调用含用子线程方法的问题

Handler和runOnUIThread都是子线程操作UI线程界面元素的方案,之前一直以为runOnUIThread能做到的Handler也能做,但是今天发现了一个问题,只能用runOnUIThread,却不能用Handler解决。


手头上有个项目用到了模拟get请求,使用的是apache的httpClient,方法如下:

private static String getHtml(final String url) {
		HttpEntity mEntity;
		try {
			HttpGet get = new HttpGet(url);
			DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
			HttpResponse httpResponse = defaultHttpClient.execute(get);
			mEntity = httpResponse.getEntity();
			return EntityUtils.toString(mEntity);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
}

安卓中强制限定了,联网请求不能在UI线程中执行,所以调用这个方法时需要开子线程,以下就是使用子线程调用以上方法的方法:

public void connectNet(){

	//我的项目中这里会先处理UI控件,所以请不要说什么这种应用场景不存在这类的话

	new Thread(new Runnable() {
		getHtml("http://www.baidu.com");
	}).start();
}
以下是一个使用场景,在子线程下使用handler来调用connectNet():
//声明一个Handler,接收子线程中的信息,调用与消息对应的方法
private Handler mHandler = new Handler() {
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case 100:
			//如果信息是100,则调用connectNet()
			connectNet();
			break;

		default:
			break;
		}
	};
};

.........某个触发事件begin........
new Thread(new Runnable() {
		.................
		
		Message msg = mHandler.obtainMessage();
		msg.what = 1000;
		mHandler.sendMessage(msg);
		
		.................
}).start();
........某个触发事件end.........

结果报错(超时):


 org.apache.http.conn.HttpHostConnectException: Connection to http://www.baidu.com refused
 	at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:188)
 	at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
 	at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
 	at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:369)
 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560)
 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492)
 	at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:470)
 	at xxxxxxx//这是我自己项目的包信息,不方便透露
 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
 	at java.lang.Thread.run(Thread.java:818)
 Caused by: java.net.ConnectException: failed to connect to /www.baidu.com (port 9999): connect failed: ETIMEDOUT (Connection timed out)
 	at libcore.io.IoBridge.connect(IoBridge.java:124)
 	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
 	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)
 	at java.net.Socket.connect(Socket.java:882)
 	at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:124)
 	at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:149)
 	... 12 more
 Caused by: android.system.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
 	at libcore.io.Posix.connect(Native Method)
 	at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:111)
 	at libcore.io.IoBridge.connectErrno(IoBridge.java:137)
 	at libcore.io.IoBridge.connect(IoBridge.java:122)
 	... 17 more

我以为方法有问题,就用按钮的点击事件来调用connectNet(),发现完全没有问题,工作正常。


分析:
1、按钮的点击事件是在UI线程中执行的,所以可以确定UI线程中可以调用connectNet(),即含有子线程的方法。
2、handler可以处理UI线程中的控件,理应属于UI线程(个人鄙见。。)。
3、猜测handler中不能执行含有子线程的操作的方法。


测试:

.........某个触发事件begin........
new Thread(new Runnable() {
		.................
		
		//用runOnUiThread代替handler
		runOnUiThread(new Runnable() {
			public void run() {
				connectNet();
			}
		});
		
		.................
}).start();
........某个触发事件end.........

结果:正常,效果与按钮的点击事件一样。








评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值