`
bing0313
  • 浏览: 9444 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Android 使用AsyncTask实现异步处理

阅读更多
    由于主线程(也可叫UI线程)负责处理用户输入事件(点击按钮、触摸屏幕、按键等),如果主线程被阻塞,应用就会报ANR错误。为了不阻塞主线程,我们需要在子线程中处理耗时的操作,在处理耗时操作的过程中,子线程可能需要更新UI控件的显示,由于UI控件的更新重绘是由主线程负责的,所以子线程需要通过Handler发送消息到主线程的消息队列中,由运行在主线程的消息处理代码接收到消息后更新UI控件的显示。
采用线程+Handler实现异步处理时,当每次执行耗时操作都创建一条新线程进行处理,性能开销会比较大。另外,如果耗时操作执行的时间比较长,就有可能同时运行着许多线程,系统将不堪重负。为了提高性能,我们可以使用AsyncTask实现异步处理,事实上其内部也是采用线程+Handler来实现异步处理的,只不过是其内部使用了线程池技术,有效地降低了线程创建数量及限定了同时运行的线程数。
public class UpdateTask extends AsyncTask<String, Integer, String>{
	protected void onPreExecute() {//运行在UI线程
	   progressBar.setMax(100);
	}
	protected String doInBackground(String... params) {
	   return "something";
	}
	protected void onPostExecute(String result) {//运行在UI线程
	    Toast.makeText(getApplicationContext(), "结果 :"+ result, 1).show();
	}
	protected void onProgressUpdate(Integer... values) {//运行在UI线程
	   progressBar.setProgress(values[0]);
	}		
}

启动异步处理工作(下面两句代码需要在主线程里执行):
UpdateTask  task = new UpdateTask();
task.execute(“liming”,“zhangxx”); //这里输入的参数会传给doInBackground()方法

停止异步处理工作:
if (task != null && task.getStatus() == AsyncTask.Status.RUNNING) {
	task.cancel(true);//如果Task还在运行,则先取消它
	task = null;
}


public class UpdateTask extends AsyncTask<String, Integer, String>{
protected void onPreExecute() {
	progressBar.setMax(100);
}
protected String doInBackground(String... params) {
	for(int i = 0 ; i < 100; i++){
	this.publishProgress(i+1);
	try {
		Thread.sleep(100);
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
	if(isCancelled()) return null; 
	}
	return "something";
}
protected void onPostExecute(String result) {
	Toast.makeText(getApplicationContext(), "结果 :"+ result, 1).show();
}
protected void onProgressUpdate(Integer... values) {
	progressBar.setProgress(values[0]);
}
}

AsyncTask类的三个泛型参数:
第一个指定了doInBackground() 方法输入参数的类型;
第二个指定了onProgressUpdate()方法输入参数的类型;
第三个指定了onPostExecute()方法输入参数的类型和doInBackground() 方法返回值的类型
这三个泛型参数的类型是根据你自己的业务需求来指定的。

onPreExecute(): 该方法在UI线程运行,当AsyncTask的execute()方法执行后,onPreExecute()会首先执行。可以在该方法中做一些准备工作,如初始化进度条的最大值。
doInBackground(Params...): 将在onPreExecute()方法执行后马上执行,该方法运行在子线程中,负责执行耗时操作。在执行耗时操作的过程中你可以不断地调用publishProgress()方法,导致onProgressUpdate()不断地被调用。
onProgressUpdate(Progress...),调用publishProgress()方法,就会导致该方法被执行,该方法运行在UI线程,例如在该方法中你可以更新进度条的显示。
onPostExecute(Result):doInBackground()方法执行后的返回结果会传给该方法,该方法运行在UI线程,在该方法中你可以显示处理结果。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics