实现异步处理----AsyncTask

来源:互联网 发布:初学英语单词软件 编辑:程序博客网 时间:2024/05/19 05:30
 

由于主线程(也可叫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 "itcast";

  }

  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 "itcast";

}

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线程,在该方法中你可以显示处理结果。

 

原创粉丝点击