android一个程序(apk)是一个进程,在程序启动时,系统启动一进程,该进程启动一个主线(UI线程),在UI线程中进行UI组件的加载和与用户交互(对用户的请求作出应答),倘若在UI线程中进行一些比较耗时的工作如:读取sd卡文件中的数据或访问数据库中的数据或者访问网络等,会造成ANR现象。所以为了提升用户体验,让自己的软件的流畅度更高一些,在UI线程中不要进行一些耗时的操作。那么这些操作应该怎么办呢?现在就像大家介绍一下android中的异步任务。

1.首先什么是异步任务?android的异步任务也可以称作后台任务,是在UI线程外启动一个线程执行耗时的任务,比用户新建线程(主次线程之间通过Handler进行通信)的好处是它可以不通过Handler通信,在任务的一个方法中直接对UI线程中的组件进行操作,他还有一个好处是可以随时获取到任务的执行进度,这对于下载和上传等操作很方便。

2.Android.os.AsyncTask类:

  ①android的类AsyncTask对线程间通讯进行了包装,提供了简易的编程方式来使后台线程和UI线程进行通讯:后台线程执行异步任务,并把操作结果通知UI线程。

  ②AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。

Params 启动任务执行的输入参数,比如HTTP请求的URL。

Progress 后台任务执行的百分比。

        Result 后台执行任务最终返回的结果,比如String,Integer等。

        这三个参数都是泛型,当然也可以自定义了。

   ③AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现这些方法。

       a.onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。

        b.doInParams...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台处理工作。此处注意将执行后得到的结果返回,还有注意此处的参数是可变参数。(可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。

        c.onProgressUpdate(Progress...),此方法是随着任务进行进度不停的进行调用。在publishProgress方法被调用后,UI 线程将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。

        d.onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户.

        e.onCancelled(),在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。

3.为了正确的使用AsyncTask类,以下是几条必须遵守的准则:

     1) Task的实例必须在UI 线程中创建

     2) execute方法必须在UI 线程中调用

     3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInParams...), onProgressUpdate(Progress...)这几个方法,需要在UI线程中实例化这个task来调用。

     4) 该task只能被执行一次,否则多次调用时将会出现异常

     doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。


详细见AsyncTaskDemo、


公司项目中,AsyncTask作为网络请求的重要工具。在onPreExecute()中做一些前期准备工作;doInParams params)中做请求网络的工作,Params是通过new AsyncTask().execute(String a, int b)传过来,在doInBackground中通过String a = (String)params[0];int b = (Integer)params[1]得到;onPostExecute()方法做得到网络请求结果后的后期工作。