UI线程如何使用AsyncTask进行异步操作

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

       AsyncTask定义了三种通用类型:Params, Progress和Result,Params表示异步任务执行时传入的参数,Progress表示异步任务执行过程中发布的数据,Result表示异步任务执行的结果。

      AsyncTask还定义了四个回调函数:onPreExecute, doInBackground, onProgressUpdate和onPostExecute来管理异步操作的过程:
     1.  onPreExecute(), 异步任务开始执行时,由UI线程调用,比如在UI上展示进度条。
     2. doInBackground(Params...), onPreExecute()执行完后,立即由后台线程调用. 该方法用来执行后台的操作,可能需要花费不少时间。参数Params传入该方法,处理结果返回并作为最后一步onPostExecute(Result) 的参数值传入。该方法内,还可以使用方法publishProgress(Progress...)来发布异步操作的进展状态,发布的进展状态数据作为 onProgressUpdate(Progress...)的参数传入,被UI线程调用。
     3. onProgressUpdate(Progress...), 和2提到的一样,该方法在publishProgress(Progress...)执行后,由UI线程调用。该方法用来在UI上展示后台操作正在执行的 任何状态,不能确定它会执行多久。比如,它可以使用动画来呈现执行过程的状态栏或者在Text里展示执行日志等。
     4. onPostExecute(Result), 后台线程操作完毕后,由UI线程调用,doInBackground(Params...)的返回值作为其参数传入。

     要实现这样的异步任务,我们必须使用一个类继承自AsyncTask,并且该子类至少要重载doInBackground(Params...)方法,我 们还经常需要重载onPostExecute(Result)方法。下面是一个继承自AsyncTask的子类的例子:
     

Java代码   收藏代码
  1. private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {  
  2.      protected Long doInBackground(URL... urls) {  
  3.          int count = urls.length;  
  4.          long totalSize = 0;  
  5.          for (int i = 0; i < count; i++) {  
  6.              totalSize += Downloader.downloadFile(urls[i]);  
  7.              publishProgress((int) ((i / (float) count) * 100));  
  8.          }  
  9.          return totalSize;  
  10.      }  
  11.   
  12.      protected void onProgressUpdate(Integer... progress) {  
  13.          setProgressPercent(progress[0]);  
  14.      }  
  15.   
  16.      protected void onPostExecute(Long result) {  
  17.          showDialog("Downloaded " + result + " bytes");  
  18.      }  
  19.  }  


      通过以下代码即可启动该异步任务:

Java代码   收藏代码
  1. new DownloadFilesTask().execute(url1, url2, url3);  



      可以通过调用方法cancel(boolean)来取消异步任务,该方法会使UI线程在方法doInBackground(Object[]) 返回后调用方法onCancelled(Object),并且方法onPostExecute(Object)将不会被调用。 cancel(boolean)调用后,应该在方法doInBackground(Object[])里周期性的检查isCancelled()的返回 值,以尽早知道异步任务是否已经取消了。

      AsyncTask实例必须在UI线程里创建,并且方法execute(Params...)必须在UI线程里执行。不要手动调用 onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) 这几个回调函数。AsyncTask实例只能被执行一次,试图去执行第二次将会跑出异常。

转载: http://akalius.iteye.com/blog/960239

猜你喜欢

转载自hongtoushizi.iteye.com/blog/2192761
今日推荐