Android异步任务执行AsyncTask使用介绍

jopen 10年前

android的主线程也就是UI线程不允许耗时的操作。否则会引起Answer Not Responding(ARN)异常。所以有两种机制用来处理耗时的操作。一种就是前面所提到的利用Handler来处理耗时的任务,还有一种就是本文介绍的一步任务处理机制:AsyncTask。所谓的异步任务机制就是UI线程符合和用户来进行流畅的交互而一些耗时的操作留给后台线程来完成。

public abstract class  AsyncTask extends Object。AsyncTask是一个抽象类。所以想利用异步任务机制来处理时必须要继承抽象类并实现类里面的抽象方法并根据需求重写类里面的方法。操作过程中一般重写它如下的几个方法:

onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.

onPreExecute():在任务被执行以前有UI主线程来调用这个函数来实现一些初始化的操作,例如在用户界面上显示一个进度条。

doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step。

doInBackGround(Params...)在onPreExecute()被调用之后由后台进程来调用这个函数来继续任务的操作。Params作为参数被传递给任务。计算的结果必须返回给最后一步操作。在这里同样可以调用publishProgress(progress...)来打印若干个进度条。在 OnProgressUpdate(Progress...)中,这些返回值就是这里 的参数progress,用来显示进度值。

onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field。

该函数由publishProgress(Progress...)调用来显示进度。

onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter。

当后台计算完成时由UI主线程调用。

当然,当我们自定义的类虽然已经继承了AsyncTask之后,我们如何来启动这个任务呢。看看对象执行调用的一些方法:

首先必须在主线程UI中创建该类的实例对象,并调用该对象的execute()方法。这样android就会自动调用这些重写的函数了。注意:该异步任务只能被execute一次,否则会抛出异常。

熟悉了这几个函数之后我们看看下面的一个例子:

public class MainActivity extends Activity {   TextView textView;   @Override   protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    textView=(TextView)findViewById(R.id.textview);   }     public void downLoad(View source)throws MalformedURLException{    DownTask task=new DownTask(this);    task.execute(10);       }      @Override   public boolean onCreateOptionsMenu(Menu menu) {    // Inflate the menu; this adds items to the action bar if it is present.    getMenuInflater().inflate(R.menu.main, menu);    return true;   }   class DownTask extends AsyncTask<Integer,Integer,String>{    Context mContext;    ProgressDialog pDialog;    int count=0;    public DownTask(Context ctx)    {     mContext=ctx;    }    @Override    protected String doInBackground(Integer... params) {     try{     for(int i=0;i<100;i++)     { Thread.sleep(500);      count++;      publishProgress(count);     }}catch(Exception e)     {      Log.v("Exception", e.getMessage());     }     return null;    }    @Override    protected void onPostExecute(String result) {     Toast.makeText(mContext, "completed", Toast.LENGTH_LONG).show();     pDialog.dismiss();         }    @Override    protected void onPreExecute() {     pDialog=new ProgressDialog(mContext);     pDialog.setMax(100);     pDialog.setTitle("下载中......");     pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);     pDialog.setIndeterminate(false);     pDialog.show();         }    @Override    protected void onProgressUpdate(Integer... values) {     pDialog.setProgress(values[0]);    }      }  }