异步任务AsyncTask

        首先,非常有必要贴点最原始东西,马上就会知道为什么 : )

AsyncTask

extends  Object
java.lang.Object
   ↳ android.os.AsyncTask<Params, Progress, Result>

        进入正题:概述

        异步任务使访问UI线程的过程变得更加简单和适当。AsyncTask允许用户在不新开线程和使用Handler的情况下,进行后台操作,并将结果直接发布到UI线程中。

        异步任务类被设计作为Thread类和Handler类的帮助类,而不是组成线程框架的一部分(AsyncTask直接继承自Object根类,其实内部还是线程基于框架实现的)。异步任务应该用于处理短时操作(最多几秒的执行时间),如果你要让当前线程保持长时间运行,那么强烈建议你使用java.util.concurrent 包下的Executor, ThreadPoolExecutor 和 FutureTask 等API类。(可参考:http://www.iteye.com/topic/366591 ,http://dongxuan.iteye.com/blog/901689

        异步任务通过计算机的后台线程生成,异步任务的结果发布在UI线程中,一个异步任务的声明过程包含三种基本类型(Param,Progress, Result)和四个步骤(onPreExecute, doInBackground, onProgressUpdate 和 onPostExecute)

     

        开发指南

        获取更多有关任务和线程的信息,可阅读文档的 Processes and Threads 部分开发指南(可参考:http://serryzhao.iteye.com/blog/1291900)。

 

        使用实例

        异步任务必须作为子类使用,子类至少应该重写doInBackground(Params...)方法,通常还会重写另外一个onPostExecute(Result)方法。下面是一个子类的实例:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

        创建以后,可以很简单地调用:

new DownloadFilesTask().execute(url1, url2, url3);
        

       异步任务的基本类型
       异步任务使用的三个基本类型如下:
       1.  Params, 被传递到任务中执行的参数类型。
       2.  Progress, 后台计算过程中发布到UI线程的进度单元类型。
       3.  Result, 后台计算的结果类型。
       通常异步任务并不会使用全部的参数类型,如果不使用该类型,则可以简单地使用Void表示。

 private class MyTask extends AsyncTask<Void, Void, Void> { ... }

       四个步骤

       一个异步任务的执行过程会经过下列四个步骤:
       1. onPreExecute(), 异步任务执行前在UI线程中调用该方法。这个步骤通常用于做准备, 如:在UI线程中展示一个进度条。 
       2. doInBackground(Params...), 在onPreExecute()执行结束后立刻由后台线程调用。这个步骤通常用于进行比较长时的后台计算。异步任务的参数在这里传递到后台。计算的结果必须通过这一步返回,并在最后一步返回到UI线程中。在进度条例子中,这一步骤中还可以通过publishProgress(Progress...)发布更多的进度单元值。这些值会通过步骤onProgressUpdate(Progress...)被发布到主线程中。
       3. onProgressUpdate(Progress...), 这一步会在调用 publishProgress(Progress...)后在主线程中运行,执行的进度会在这一步中更行。如果后台计算仍在进行,那么这一步可以在界面上展示任何形式的进度,如,通过动画形式的进度条在文本域中展示日志。
       4. onPostExecute(Result), 后台计算完成后,在主线程中调用,后台计算的结果会在这一步中作为参数返回。


        取消异步任务

        通过调用cancel(boolean)可以在任何时候取消一个异步任务。调用这个方法后会调用isCancelled()返回一个true值。 如果调用cancel(boolean)方法,那么doInBackground(Object[]) 方法返回后会调用 onCancelled(Object)而不是onPostExecute(Object) 。如果要尽快确认一个异步任务是否被取消了,你应该周期性地在doInBackground(Object[])中检查isCancelled()的返回值 。


         线程规则

        下面是一些异步任务运行过程中必须要注意的线程规则:
        * 异步任务类必须在主线程中加载,在android4.1 JELLY_BEAN版本中,这是自动进行的。 
        * 异步任务的实例必须在UI线程中调用。
        * execute(Params...)方法必须在主线程中调用。
        * 不要主动调用 onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)等方法。
        * 异步任务只会被执行一次(如果重复执行,则会抛出异常)


        内存监督

        异步任务确保所有的回调方法都是同步的,所以在不明确指明同步的情况下,下列操作都是线程安全的。
        * 在构造方法或onPreExecute()中设置成员属性,并在doInBackground(Params...).中引用这些属性。
        * 在doInBackground(Params...)中设置成员属性,并在 onProgressUpdate(Progress...)和onPostExecute(Result)中引用这些属性。


        执行顺序
        首次引用时, 异步任务会在一个单一的后台线程中有序执行。从DONUT版本开始,异步任务被放到线程池中执行,并允许多任务并行执行。从HONEYCOMB版本开始,异步任务在独立的线程池中执行,以避免异步任务并行执行导致的公共应用错误。
        如果你确实想让异步任务并行执行,那么你可以通过THREAD_POOL_EXECUTOR 调用 executeOnExecutor(java.util.concurrent.Executor, Object[])。


        更多详情分析和源码理解可以参考这些文章;

       http://blog.csdn.net/mylzc/article/details/6784415

       http://blog.csdn.net/mylzc/article/details/6774131

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值