Android知识点之多线程:Thread、AsyncTask、IntentService

转载请注明本文出自天水笑微的博客(http://blog.csdn.net/fuhaijing2013/article/details/62226825,谢谢支持!


Android的线程主要分两种:主线程和子线程。主线程主要负责处理UI相关的操作,子线程主要负责一些耗时操作,各司其职,如果主线程中处理一些耗时操作(一般大于5s)就会导致程序无法响应异常,同时如果子线程越权处理更新UI操作,亦会出现异常,这也就是大家平常说的Android是线程不安全的。(虽然多有不便,想想也有道理,如果多个线程同时操作UI,那不乱套才怪。)

Android系统提供的线程实现方式主要有:原生的Thread、轻量级AsyncTask、服务IntentService、HandlerThread。


一、Thread+Handler或runOnUiThread实现方式


Thread+handler实现方式基本思路是,开启一个子线程Thread,实现Runnable接口,在run()函数中执行一些耗时操作,然后通过Message与Handler通信,通过Handler切换到主线程中实现UI更新操作(如果不需要更新UI就不需要Handler了,不过这种情况比较少)。代码如下:

protected void DataParerThread() {
		Runnable target = new Runnable() {
			public void run() {
					//耗时操作
					//...
				Message msg = Message.obtain();
				msg.what = 0;
				msg.obj = message;
				handler.sendMessage(msg);
			}
		};
		new Thread(target).start();
	}
}	

private Handler handler = new Handler(){
	@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case 0:
			//UI 操作
		super.handleMessage(msg);
	}	
};


Thread+runOnUiThread方式更紧凑一些,直接在Run()函数里通过runOnUiThread函数切换到主线程,实现UI操作。

	protected void DataParerThread() {
		Runnable target = new Runnable() {
			public void run() {
					//耗时操作
					//...
					runOnUiThread(new Runnable() {
						public void run() {
							//更新UI操作
						}
					}

			}
		};
		new Thread(target).start();
	}


二、AsyncTask封装

AsyncTask是一种轻量级的异步任务类,封装了Thread+handler,底层用到了线程池,是Android为了简化子线程中访问UI的过程而推出的异步实现方式,比Thread+handler更加轻量级,适合并不是特别耗时的后出台任务。

主要有四个核心方法:doInBackground(Params…),onPostExecute(Result),onPreExecute() onProgressUpdate(Progress…) ,至少覆盖前两个方法

   doInBackground(Params…) 后台执行,比较耗时的操作,这里不能直接操作UI。执行过程中可以调用publicProgress(Progress…)来更新任务的进度。

     onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。

    onProgressUpdate(Progress…) 可以使用进度条增加用户体验度。

   onPreExecute() 这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框

   private myAsyncTask extends AsyncTask{
    @Override
    protected void onPreExecute(){
         Log.v("TestActivity","开始执行异步线程");
    }
    /**
    * 这里的Integer参数对应AsyncTask中的第一个参数
    * 这里的String返回值对应AsyncTask的第三个参数
    * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
    */
    @Override
    protected String doInBackground(Integer...params){
         // 加载网络数据,耗时操作
    }
    @Override
    protected void onPostExecute(Stringresult){
        Log.v("TestActivity","结束执行异步线程");
        // 更新UI
    }
}


三、特殊服务IntentService

IntentService是一种特殊的Service,内部封装了HandlerThread和Handler,与service的不同是当任务结束后可以自己杀死自己节约内存。

可用于执行后台耗时任务,与前两种相比优点是优先级比较高,所以这种方式比较适合执行一些优先级比较高的耗时任务,不容易被杀死。


四、HandlerThread 

HandlerThread集成了Thread,是一种可以使用Handler的Thread,很少单独用吧。


五、异同

1) 实现方式方面,AsyncTask方式做了比较好的封装,逻辑更清晰,原生的Thread+Runnable+Handler方式代码不够紧凑(其实还好啦)

2) 性能方面,有一种说法是AsyncTask比起Thread方式耗内存,感觉没啥差别吧,毕竟AsyncTask也是通过封装原生Thread实现的,具体也没验证。

3)灵活性方面,AsyncTask对UI的控制更灵活一些,可以通过提供的接口函数实时更新UI

4)功能方面,AsyncTask的一个缺点是不能灵活的控制线程池,加入一个页面有50个AsyncTask线程访问,切换到另一个界面,新的线程访问可能排到50名开外了,取消操作和优先级设定不好控制。如果遇到这种情况,推荐一些自己封装的ThreadPoolExecutor方式。


六、使用总结

Android为了更方便的在线程中操作Ui,延伸出了AsyncTask,因此如果需要用到与界面相关的线程且不太复杂的时候首选AsyncTask,如果线程主要用来处理数据,不参与界面操作的时候尽量用Thread线程。另外如果在应用中需要启动多个线程的时候,也要使用Thread,它自带多线程处理。AsyncTask适合一些少数数据量的操作。

其实,我平时更倾向于用Tread+runOnUiThread()方式实现,没那么臃肿,还好处多多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值