AsyncTask在包android.os中,使用AsyncTask能够使得和UI 线程的交互更为简单合适。它可以用来进行后台的操作,并且把结果显示在UI线程上,而不需要程序员自己人为的对线程(Thread or Handler)进行控制和管理。
这个类通过3个泛型参数(params,progress,result),和4个步骤(begin,doinbackground,processProgress,end)来定义。
http://blog.csdn.net/dww410/article/details/6605467 
(一)三个泛型参数params,progress,result 
这个三个参数可为任何类型和任何类型的数组,如果不需要,则用Void代替。
params对应于doInbackground(Params…parames)
progress对应于onProgressUpdate()和publishProgress(Progress…progress),用来反应线程执行的进度,其中publishProgress方法必须在doInBackground方法中调用。
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
             Result  doInBackground () 
                { 
          A ();             //方法A,从网络读取数据 
                      this . publishProgress ( "state1" , "I like it" ); 
                       B ();           //方法B,复杂的计算处理 
                       this . publishProgress ( "state2" , "for test" ); 
                       return  result ; 
        } 
               onProgressUpdate ( String  values ) 
               { 
                    if ( values [ 0 ]. equals ( "state1" )) 
                           C ();         //将A读取的数据在UI上展现 
                    else  if ( values [ 0 ]. equals ( "state2" )) 
                          Log . e ( "value" , values [ 1 ]); 
       } 
 
result后台进程计算得出的结果,对应于onPostExecute(Result),后台进程得出的结果,作为参数传递给此方法。
(二)四个步骤和对应的方法 
(1)begin和onPreExecute()
任务启动后(通过execute()方法启动任务),这个步骤用来在UI线程中做一些初始化的工作,比如展现一个进度条。
(2)doInBackground和doInBackground()
当onPreExecute()方法执行完后,这个步骤立即在后台线程运行,用来处理一些耗时的计算及其他引起UI线程阻塞的操作,处理的结果result返回给onPostExecute(Result)方法,也可以使用publishProgress()和UI线程进行交互,上面已有例子。
(3)processProgress和onProgressUpdate()
每次当在后台线程里调用了publishProgress()方法后,onProgressUpdate()都会在UI线程中执行。这个步骤在后台线程还未结束时,用来进行UI线程和后台线程的交互。
(4)end和onPostExecute()
当后台线程执行完毕之后,后台线程将得到的结果传递给onPostExecute()方法,这个步骤在UI线程上展现后台线程执行完毕后最终得到的结果。
上面这四个方法都是只有doInBackground()是在后台线程中执行,其他都是在UI线程中执行。 这四个方法都是protected,必须继承的使用AsyncTask类,必须重写doInbackground()方法,经常还要重写onPostExecute()方法。
当然具体重写哪些方法根据实际需要决定,如果要在后台进程尚未执行完成需要和UI交互,就要重写onProgressUpdate()方法,如果只需要等后台进程执行完毕得到结果后再和UI交互,则重写onPostExecute()方法就行。
(三)使用AsyncTask遵循的线程规则 
(1)这个类的实例必须在UI线程中创建。
(2)execute()必须在UI线程中调用。
(3)不要自己动手去调用上面的四个方法。
(4)这个任务只能被执行一次,如果尝试多次执行会抛出异常。
详解Android中AsyncTask的使用 
http://blog.csdn.net/liuhe688/article/details/6532519 
在Android中实现异步任务机制有两种方式,Handler和AsyncTask。
Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。关于Handler的相关知识,前面也有所介绍,不清楚的朋友们可以参照一下。
为了简化操作,Android1.5提供了工具类android.os.AsyncTask,它使创建异步任务变得更加简单,不再需要编写任务线程和Handler实例即可完成相同的任务。
先来看看AsyncTask的定义:
[java] view plain
copy
public abstract class AsyncTask<Params, Progress, Result> {
三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。在特定场合下,并不是所有类型都被使用,如果没有被使用,可以用java.lang.Void类型代替。
一个异步任务的执行一般包括以下几个步骤:
1.execute(Params… params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute(),在execute(Params… params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params… params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress… values)来更新进度信息。
4.onProgressUpdate(Progress… values),在调用publishProgress(Progress… values)时,此方法被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
在使用的时候,有几点需要格外注意:
1.异步任务的实例必须在UI线程中创建。
2.execute(Params… params)方法必须在UI线程中调用。
3.不要手动调用onPreExecute(),doInBackground(Params… params),onProgressUpdate(Progress… values),onPostExecute(Result result)这几个方法。
4.不能在doInBackground(Params… params)中更改UI组件的信息。
5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。
接下来,我们来看看如何使用AsyncTask执行异步任务操作,我们先建立一个项目,结构如下:
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
98 
99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
结构相对简单一些,让我们先看看 MainActivity . java 的代码: 
 [ java ]  view  plain 
copy 
 package  com . scott . async ; 
 import  java.io.ByteArrayOutputStream ; 
import  java.io.InputStream ; 
 import  org.apache.http.HttpEntity ; 
import  org.apache.http.HttpResponse ; 
import  org.apache.http.HttpStatus ; 
import  org.apache.http.client.HttpClient ; 
import  org.apache.http.client.methods.HttpGet ; 
import  org.apache.http.impl.client.DefaultHttpClient ; 
 import  android.app.Activity ; 
import  android.os.AsyncTask ; 
import  android.os.Bundle ; 
import  android.util.Log ; 
import  android.view.View ; 
import  android.widget.Button ; 
import  android.widget.ProgressBar ; 
import  android.widget.TextView ; 
 public  class  MainActivity  extends  Activity  { 
     private  static  final  String  TAG  =  "ASYNC_TASK" ; 
 
     private  Button  execute ; 
     private  Button  cancel ; 
     private  ProgressBar  progressBar ; 
     private  TextView  textView ; 
 
     private  MyTask  mTask ; 
 
     @Override 
     public  void  onCreate ( Bundle  savedInstanceState )  { 
         super . onCreate ( savedInstanceState ); 
         setContentView ( R . layout . main ); 
 
         execute  =  ( Button )  findViewById ( R . id . execute ); 
         execute . setOnClickListener ( new  View . OnClickListener ()  { 
             @Override 
             public  void  onClick ( View  v )  { 
                 //注意每次需new一个实例,新建的任务只能执行一次,否则会出现异常   
                 mTask  =  new  MyTask (); 
                 mTask . execute ( "http://www.baidu.com" ); 
 
                 execute . setEnabled ( false ); 
                 cancel . setEnabled ( true ); 
             } 
         }); 
         cancel  =  ( Button )  findViewById ( R . id . cancel ); 
         cancel . setOnClickListener ( new  View . OnClickListener ()  { 
             @Override 
             public  void  onClick ( View  v )  { 
                 //取消一个正在执行的任务,onCancelled方法将会被调用   
                 mTask . cancel ( true ); 
             } 
         }); 
         progressBar  =  ( ProgressBar )  findViewById ( R . id . progress_bar ); 
         textView  =  ( TextView )  findViewById ( R . id . text_view ); 
 
     } 
 
     private  class  MyTask  extends  AsyncTask < String ,  Integer ,  String >  { 
         //onPreExecute方法用于在执行后台任务前做一些UI操作   
         @Override 
         protected  void  onPreExecute ()  { 
             Log . i ( TAG ,  "onPreExecute() called" ); 
             textView . setText ( "loading..." ); 
         } 
 
         //doInBackground方法内部执行后台任务,不可在此方法内修改UI   
         @Override 
         protected  String  doInBackground ( String ...  params )  { 
             Log . i ( TAG ,  "doInBackground(Params... params) called" ); 
             try  { 
                 HttpClient  client  =  new  DefaultHttpClient (); 
                 HttpGet  get  =  new  HttpGet ( params [ 0 ]); 
                 HttpResponse  response  =  client . execute ( get ); 
                 if  ( response . getStatusLine (). getStatusCode ()  ==  HttpStatus . SC_OK )  { 
                     HttpEntity  entity  =  response . getEntity (); 
                     InputStream  is  =  entity . getContent (); 
                     long  total  =  entity . getContentLength (); 
                     ByteArrayOutputStream  baos  =  new  ByteArrayOutputStream (); 
                     byte []  buf  =  new  byte [ 1024 ]; 
                     int  count  =  0 ; 
                     int  length  =  - 1 ; 
                     while  (( length  =  is . read ( buf ))  !=  - 1 )  { 
                         baos . write ( buf ,  0 ,  length ); 
                         count  +=  length ; 
                         //调用publishProgress公布进度,最后onProgressUpdate方法将被执行   
                         publishProgress (( int )  (( count  /  ( float )  total )  *  100 )); 
                         //为了演示进度,休眠500毫秒   
                         Thread . sleep ( 500 ); 
                     } 
                     return  new  String ( baos . toByteArray (),  "utf-8" ); 
                 } 
             }  catch  ( Exception  e )  { 
                 Log . e ( TAG ,  e . getMessage ()); 
             } 
             return  null ; 
         } 
 
         //onProgressUpdate方法用于更新进度信息   
         @Override 
         protected  void  onProgressUpdate ( Integer ...  progresses )  { 
             Log . i ( TAG ,  "onProgressUpdate(Progress... progresses) called" ); 
             progressBar . setProgress ( progresses [ 0 ]); 
             textView . setText ( "loading..."  +  progresses [ 0 ]  +  "%" ); 
         } 
 
         //onPostExecute方法用于在执行完后台任务后更新UI,显示结果   
         @Override 
         protected  void  onPostExecute ( String  result )  { 
             Log . i ( TAG ,  "onPostExecute(Result result) called" ); 
             textView . setText ( result ); 
 
             execute . setEnabled ( true ); 
             cancel . setEnabled ( false ); 
         } 
 
         //onCancelled方法用于在取消执行中的任务时更改UI   
         @Override 
         protected  void  onCancelled ()  { 
             Log . i ( TAG ,  "onCancelled() called" ); 
             textView . setText ( "cancelled" ); 
             progressBar . setProgress ( 0 ); 
 
             execute . setEnabled ( true ); 
             cancel . setEnabled ( false ); 
         } 
     } 
 } 
 
布局文件main.xml代码如下:
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout  xmlns:android= "http://schemas.android.com/apk/res/android" 
    android:orientation= "vertical" 
     android:layout_width= "fill_parent" 
     android:layout_height= "fill_parent" > 
     <Button 
         android:id= "@+id/execute" 
         android:layout_width= "fill_parent" 
         android:layout_height= "wrap_content" 
         android:text= "execute" /> 
     <Button 
         android:id= "@+id/cancel" 
         android:layout_width= "fill_parent" 
         android:layout_height= "wrap_content" 
         android:enabled= "false" 
         android:text= "cancel" /> 
     <ProgressBar 
         android:id= "@+id/progress_bar" 
         android:layout_width= "fill_parent" 
         android:layout_height= "wrap_content" 
         android:progress= "0" 
         android:max= "100" 
         style= "?android:attr/progressBarStyleHorizontal" /> 
     <ScrollView 
         android:layout_width= "fill_parent" 
         android:layout_height= "wrap_content" > 
         <TextView 
             android:id= "@+id/text_view" 
             android:layout_width= "fill_parent" 
             android:layout_height= "wrap_content" /> 
     </ScrollView> 
 </LinearLayout> 
 
因为需要访问网络,所以我们还需要在AndroidManifest.xml中加入访问网络的权限:
 1 
<uses-permission  android:name= "android.permission.INTERNET" /> 
 
我们来看一下运行时的界面:
以上几个截图分别是初始界面、执行异步任务时界面、执行成功后界面、取消任务后界面。执行成功后,整个过程日志打印如下:
如果我们在执行任务时按下了“cancel”按钮,日志打印如下:
可以看到onCancelled()方法将会被调用,onPostExecute(Result result)方法将不再被调用。
上面介绍了AsyncTask的基本应用,有些朋友也许会有疑惑,AsyncTask内部是怎么执行的呢,它执行的过程跟我们使用Handler又有什么区别呢?答案是:AsyncTask是对Thread+Handler良好的封装,在android.os.AsyncTask代码里仍然可以看到Thread和Handler的踪迹。下面就向大家详细介绍一下AsyncTask的执行原理。
我们先看一下AsyncTask的大纲视图:
我们可以看到关键几个步骤的方法都在其中,doInBackground(Params… params)是一个抽象方法,我们继承AsyncTask时必须覆写此方法;onPreExecute()、onProgressUpdate(Progress… values)、onPostExecute(Result result)、onCancelled()这几个方法体都是空的,我们需要的时候可以选择性的覆写它们;publishProgress(Progress… values)是final修饰的,不能覆写,只能去调用,我们一般会在doInBackground(Params… params)中调用此方法;另外,我们可以看到有一个Status的枚举类和getStatus()方法,Status枚举类代码段如下:
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
        //初始状态 
   private  volatile  Status  mStatus  =  Status . PENDING ; 
   
   public  enum  Status  { 
         /** 
          * Indicates that the task has not been executed yet. 
         */ 
        PENDING , 
         /** 
          * Indicates that the task is running. 
         */ 
        RUNNING , 
         /** 
          * Indicates that {@link AsyncTask#onPostExecute} has finished. 
         */ 
        FINISHED , 
     } 
 
 /** 
     * Returns the current status of this task. 
     * 
     * @return The current status. 
     */ 
    public  final  Status  getStatus ()  { 
         return  mStatus ; 
     } 
 
 
可以看到,AsyncTask的初始状态为PENDING,代表待定状态,RUNNING代表执行状态,FINISHED代表结束状态,这几种状态在AsyncTask一次生命周期内的很多地方被使用,非常重要。
介绍完大纲视图相关内容之后,接下来,我们会从execute(Params… params)作为入口,重点分析一下AsyncTask的执行流程,我们来看一下execute(Params… params)方法的代码段:
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
public  final  AsyncTask < Params ,  Progress ,  Result >  execute ( Params ...  params )  { 
        if  ( mStatus  !=  Status . PENDING )  { 
             switch  ( mStatus )  { 
                 case  RUNNING: 
                   //如果该任务正在被执行则抛出异常 
                   //值得一提的是,在调用cancel取消任务后,状态仍未RUNNING 
                     throw  new  IllegalStateException ( "Cannot execute task:" 
                             +  " the task is already running." ); 
                 case  FINISHED: 
                   //如果该任务已经执行完成则抛出异常 
                     throw  new  IllegalStateException ( "Cannot execute task:" 
                             +  " the task has already been executed " 
                             +  "(a task can be executed only once)" ); 
             } 
         } 
       
       //改变状态为RUNNING 
         mStatus  =  Status . RUNNING ; 
 
       //调用onPreExecute方法 
         onPreExecute (); 
 
         mWorker . mParams  =  params ; 
         sExecutor . execute ( mFuture ); 
 
         return  this ; 
     } 
 
 
代码中涉及到三个陌生的变量:mWorker、sExecutor、mFuture,我们也会看一下他们的庐山真面目:
关于sExecutor,它是java.util.concurrent.ThreadPoolExecutor的实例,用于管理线程的执行。代码如下:
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
 private  static  final  int  CORE_POOL_SIZE  =  5 ; 
     private  static  final  int  MAXIMUM_POOL_SIZE  =  128 ; 
     private  static  final  int  KEEP_ALIVE  =  10 ; 
 
   //新建一个队列用来存放线程 
     private  static  final  BlockingQueue < Runnable >  sWorkQueue  = 
             new  LinkedBlockingQueue < Runnable >( 10 ); 
   //新建一个线程工厂 
     private  static  final  ThreadFactory  sThreadFactory  =  new  ThreadFactory ()  { 
         private  final  AtomicInteger  mCount  =  new  AtomicInteger ( 1 ); 
       //新建一个线程 
         public  Thread  newThread ( Runnable  r )  { 
             return  new  Thread ( r ,  "AsyncTask #"  +  mCount . getAndIncrement ()); 
         } 
     }; 
   //新建一个线程池执行器,用于管理线程的执行 
     private  static  final  ThreadPoolExecutor  sExecutor  =  new  ThreadPoolExecutor ( CORE_POOL_SIZE , 
             MAXIMUM_POOL_SIZE ,  KEEP_ALIVE ,  TimeUnit . SECONDS ,  sWorkQueue ,  sThreadFactory ); 
 
 
mWorker实际上是AsyncTask的一个的抽象内部类的实现对象实例,它实现了Callable接口中的call()方法,代码如下: 
 1 
2 
3 
private  static  abstract  class  WorkerRunnable < Params ,  Result >  implements  Callable < Result >  { 
        Params []  mParams ; 
     } 
 
 
而mFuture实际上是java.util.concurrent.FutureTask的实例,下面是它的FutureTask类的相关信息:
 1 
2 
3 
4 
5 
/** 
 * A cancellable asynchronous computation. 
 * ... 
 */ 
public  class  FutureTask < V >  implements  RunnableFuture < V >  { 
 
 1 
2 
3 
4 
5 
6 
7 
public  interface  RunnableFuture < V >  extends  Runnable ,  Future < V >  { 
    /** 
      * Sets this Future to the result of its computation 
     * unless it has been cancelled. 
     */ 
    void  run (); 
 } 
 
可以看到FutureTask是一个可以中途取消的用于异步计算的类。
下面是mWorker和mFuture实例在AsyncTask中的体现:
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
    private  final  WorkerRunnable < Params ,  Result >  mWorker ; 
     private  final  FutureTask < Result >  mFuture ; 
   
   public  AsyncTask ()  { 
         mWorker  =  new  WorkerRunnable < Params ,  Result >()  { 
             //call方法被调用后,将设置优先级为后台级别,然后调用AsyncTask的doInBackground方法 
           public  Result  call ()  throws  Exception  { 
                 Process . setThreadPriority ( Process . THREAD_PRIORITY_BACKGROUND ); 
                 return  doInBackground ( mParams ); 
             } 
         }; 
 
       //在mFuture实例中,将会调用mWorker做后台任务,完成后会调用done方法 
         mFuture  =  new  FutureTask < Result >( mWorker )  { 
             @Override 
             protected  void  done ()  { 
                 Message  message ; 
                 Result  result  =  null ; 
 
                 try  { 
                     result  =  get (); 
                 }  catch  ( InterruptedException  e )  { 
                     android . util . Log . w ( LOG_TAG ,  e ); 
                 }  catch  ( ExecutionException  e )  { 
                     throw  new  RuntimeException ( "An error occured while executing doInBackground()" , 
                             e . getCause ()); 
                 }  catch  ( CancellationException  e )  { 
                   //发送取消任务的消息 
                     message  =  sHandler . obtainMessage ( MESSAGE_POST_CANCEL , 
                             new  AsyncTaskResult < Result >( AsyncTask . this ,  ( Result [])  null )); 
                     message . sendToTarget (); 
                     return ; 
                 }  catch  ( Throwable  t )  { 
                     throw  new  RuntimeException ( "An error occured while executing " 
                             +  "doInBackground()" ,  t ); 
                 } 
 
               //发送显示结果的消息 
                 message  =  sHandler . obtainMessage ( MESSAGE_POST_RESULT , 
                         new  AsyncTaskResult < Result >( AsyncTask . this ,  result )); 
                 message . sendToTarget (); 
             } 
         }; 
     } 
 
 
我们看到上面的代码中,mFuture实例对象的done()方法中,如果捕捉到了CancellationException类型的异常,则发送一条“MESSAGE_POST_CANCEL”的消息;如果顺利执行,则发送一条“MESSAGE_POST_RESULT”的消息,而消息都与一个sHandler对象关联。这个sHandler实例实际上是AsyncTask内部类InternalHandler的实例,而InternalHandler正是继承了Handler,下面我们来分析一下它的代码:
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
 private  static  final  int  MESSAGE_POST_RESULT  =  0x1 ;     //显示结果 
     private  static  final  int  MESSAGE_POST_PROGRESS  =  0x2 ;     //更新进度 
     private  static  final  int  MESSAGE_POST_CANCEL  =  0x3 ;   //取消任务 
 
     private  static  final  InternalHandler  sHandler  =  new  InternalHandler (); 
   
   private  static  class  InternalHandler  extends  Handler  { 
         @SuppressWarnings ({ "unchecked" ,  "RawUseOfParameterizedType" }) 
         @Override 
         public  void  handleMessage ( Message  msg )  { 
             AsyncTaskResult  result  =  ( AsyncTaskResult )  msg . obj ; 
             switch  ( msg . what )  { 
                 case  MESSAGE_POST_RESULT: 
                     // There is only one result 
                   //调用AsyncTask.finish方法 
                     result . mTask . finish ( result . mData [ 0 ]); 
                     break ; 
                 case  MESSAGE_POST_PROGRESS: 
                     //调用AsyncTask.onProgressUpdate方法 
                   result . mTask . onProgressUpdate ( result . mData ); 
                     break ; 
                 case  MESSAGE_POST_CANCEL: 
                   //调用AsyncTask.onCancelled方法 
                     result . mTask . onCancelled (); 
                     break ; 
             } 
         } 
     } 
 
 
我们看到,在处理消息时,遇到“MESSAGE_POST_RESULT”时,它会调用AsyncTask中的finish()方法,我们来看一下finish()方法的定义:
 1 
2 
3 
4 
5 
private  void  finish ( Result  result )  { 
        if  ( isCancelled ())  result  =  null ; 
         onPostExecute ( result );     //调用onPostExecute显示结果 
         mStatus  =  Status . FINISHED ;  //改变状态为FINISHED 
     } 
 
 
原来finish()方法是负责调用onPostExecute(Result result)方法显示结果并改变任务状态的啊。
另外,在mFuture对象的done()方法里,构建一个消息时,这个消息包含了一个AsyncTaskResult类型的对象,然后在sHandler实例对象的handleMessage(Message msg)方法里,使用下面这种方式取得消息中附带的对象:
 1 
AsyncTaskResult  result  =  ( AsyncTaskResult )  msg . obj ; 
 
这个AsyncTaskResult究竟是什么呢,它又包含什么内容呢?其实它也是AsyncTask的一个内部类,是用来包装执行结果的一个类,让我们来看一下它的代码结构:
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
    @SuppressWarnings ({ "RawUseOfParameterizedType" }) 
     private  static  class  AsyncTaskResult < Data >  { 
         final  AsyncTask  mTask ; 
         final  Data []  mData ; 
 
         AsyncTaskResult ( AsyncTask  task ,  Data ...  data )  { 
             mTask  =  task ; 
             mData  =  data ; 
         } 
     } 
 
 
看以看到这个AsyncTaskResult封装了一个AsyncTask的实例和某种类型的数据集,我们再来看一下构建消息时的代码:
 1 
2 
3 
4 
//发送取消任务的消息 
message  =  sHandler . obtainMessage ( MESSAGE_POST_CANCEL , 
        new  AsyncTaskResult < Result >( AsyncTask . this ,  ( Result [])  null )); 
 message . sendToTarget (); 
 
 1 
2 
3 
4 
//发送显示结果的消息 
message  =  sHandler . obtainMessage ( MESSAGE_POST_RESULT , 
         new  AsyncTaskResult < Result >( AsyncTask . this ,  result )); 
 message . sendToTarget (); 
 
在处理消息时是如何使用这个对象呢,我们再来看一下:
 1 
result . mTask . finish ( result . mData [ 0 ]); 
 
 1 
result . mTask . onProgressUpdate ( result . mData ); 
 
概括来说,当我们调用execute(Params… params)方法后,execute方法会调用onPreExecute()方法,然后由ThreadPoolExecutor实例sExecutor执行一个FutureTask任务,这个过程中doInBackground(Params… params)将被调用,如果被开发者覆写的doInBackground(Params… params)方法中调用了publishProgress(Progress… values)方法,则通过InternalHandler实例sHandler发送一条MESSAGE_POST_PROGRESS消息,更新进度,sHandler处理消息时onProgressUpdate(Progress… values)方法将被调用;如果遇到异常,则发送一条MESSAGE_POST_CANCEL的消息,取消任务,sHandler处理消息时onCancelled()方法将被调用;如果执行成功,则发送一条MESSAGE_POST_RESULT的消息,显示结果,sHandler处理消息时onPostExecute(Result result)方法被调用。
经过上面的介绍,相信朋友们都已经认识到AsyncTask的本质了,它对Thread+Handler的良好封装,减少了开发者处理问题的复杂度,提高了开发效率,希望朋友们能多多体会一下。