AsyncTask的实现原理

概述:AsyncTask的本质是一个线程池,所有提交的异步任务都会在这个线程池中的工作线程内执行,当工作线程需要跟UI线程交互时,工作线程会通过向在UI线程创建的Handler(原理见:《Handler+Looper+MessageQueue深入详解》传递消息的方式,调用相关的回调函数,从而实现UI界面的更新。

例子:

例子:

本章还是以《Handler+Looper+MessageQueue深入详解》中的例子说明AsyncTask的实现原理。

这个例子是在后台下载CSDN的LOGO,下载完成后在UI界面上显示出来。

AsyncTask.java
  1. package com.zhuozhuo;  
  2.   
  3.   
  4. import org.apache.http.HttpResponse;  
  5. import org.apache.http.client.HttpClient;  
  6. import org.apache.http.client.methods.HttpGet;  
  7. import org.apache.http.impl.client.DefaultHttpClient;  
  8.   
  9. import android.app.Activity;  
  10. import android.graphics.Bitmap;  
  11. import android.graphics.BitmapFactory;  
  12. import android.os.AsyncTask;  
  13. import android.os.Bundle;  
  14. import android.view.View;  
  15. import android.view.View.OnClickListener;  
  16. import android.widget.Button;  
  17. import android.widget.ImageView;  
  18. import android.widget.ProgressBar;  
  19. import android.widget.Toast;  
  20.   
  21. public class AsyncTaskActivity extends Activity {  
  22.       
  23.     private ImageView mImageView;  
  24.     private Button mButton;  
  25.     private ProgressBar mProgressBar;  
  26.       
  27.     @Override  
  28.     public void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.main);  
  31.           
  32.         mImageView= (ImageView) findViewById(R.id.imageView);  
  33.         mButton = (Button) findViewById(R.id.button);  
  34.         mProgressBar = (ProgressBar) findViewById(R.id.progressBar);  
  35.         mButton.setOnClickListener(new OnClickListener() {  
  36.               
  37.             @Override  
  38.             public void onClick(View v) {  
  39.                 GetCSDNLogoTask task = new GetCSDNLogoTask();  
  40.                 task.execute("http://csdnimg.cn/www/images/csdnindex_logo.gif");  
  41.             }  
  42.         });  
  43.     }  
  44.       
  45.     class GetCSDNLogoTask extends AsyncTask<String,Integer,Bitmap> {//继承AsyncTask   
  46.   
  47.         @Override  
  48.         protected Bitmap doInBackground(String... params) {//处理后台执行的任务,在后台线程执行   
  49.             publishProgress(0);//将会调用onProgressUpdate(Integer... progress)方法   
  50.             HttpClient hc = new DefaultHttpClient();  
  51.             publishProgress(30);  
  52.             HttpGet hg = new HttpGet(params[0]);//获取csdn的logo   
  53.             final Bitmap bm;  
  54.             try {  
  55.                 HttpResponse hr = hc.execute(hg);  
  56.                 bm = BitmapFactory.decodeStream(hr.getEntity().getContent());  
  57.             } catch (Exception e) {  
  58.                   
  59.                 return null;  
  60.             }  
  61.             publishProgress(100);  
  62.             //mImageView.setImageBitmap(result); 不能在后台线程操作ui   
  63.             return bm;  
  64.         }  
  65.           
  66.         protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用,在ui线程执行   
  67.             mProgressBar.setProgress(progress[0]);//更新进度条的进度   
  68.          }  
  69.   
  70.          protected void onPostExecute(Bitmap result) {//后台任务执行完之后被调用,在ui线程执行   
  71.              if(result != null) {  
  72.                  Toast.makeText(AsyncTaskActivity.this"成功获取图片", Toast.LENGTH_LONG).show();  
  73.                  mImageView.setImageBitmap(result);  
  74.              }else {  
  75.                  Toast.makeText(AsyncTaskActivity.this"获取图片失败", Toast.LENGTH_LONG).show();  
  76.              }  
  77.          }  
  78.            
  79.          protected void onPreExecute () {//在 doInBackground(Params...)之前被调用,在ui线程执行   
  80.              mImageView.setImageBitmap(null);  
  81.              mProgressBar.setProgress(0);//进度条复位   
  82.          }  
  83.            
  84.          protected void onCancelled () {//在ui线程执行   
  85.              mProgressBar.setProgress(0);//进度条复位   
  86.          }  
  87.           
  88.     }  
  89. }  
package com.zhuozhuo;


import org.apache.http.HttpResponse;
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.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;

public class AsyncTaskActivity extends Activity {
    
	private ImageView mImageView;
	private Button mButton;
	private ProgressBar mProgressBar;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mImageView= (ImageView) findViewById(R.id.imageView);
        mButton = (Button) findViewById(R.id.button);
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
        mButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				GetCSDNLogoTask task = new GetCSDNLogoTask();
				task.execute("http://csdnimg.cn/www/images/csdnindex_logo.gif");
			}
		});
    }
    
    class GetCSDNLogoTask extends AsyncTask<String,Integer,Bitmap> {//继承AsyncTask

		@Override
		protected Bitmap doInBackground(String... params) {//处理后台执行的任务,在后台线程执行
			publishProgress(0);//将会调用onProgressUpdate(Integer... progress)方法
			HttpClient hc = new DefaultHttpClient();
			publishProgress(30);
			HttpGet hg = new HttpGet(params[0]);//获取csdn的logo
			final Bitmap bm;
			try {
				HttpResponse hr = hc.execute(hg);
				bm = BitmapFactory.decodeStream(hr.getEntity().getContent());
			} catch (Exception e) {
				
				return null;
			}
			publishProgress(100);
			//mImageView.setImageBitmap(result); 不能在后台线程操作ui
			return bm;
		}
		
		protected void onProgressUpdate(Integer... progress) {//在调用publishProgress之后被调用,在ui线程执行
			mProgressBar.setProgress(progress[0]);//更新进度条的进度
	     }

	     protected void onPostExecute(Bitmap result) {//后台任务执行完之后被调用,在ui线程执行
	    	 if(result != null) {
	    		 Toast.makeText(AsyncTaskActivity.this, "成功获取图片", Toast.LENGTH_LONG).show();
	    		 mImageView.setImageBitmap(result);
	    	 }else {
	    		 Toast.makeText(AsyncTaskActivity.this, "获取图片失败", Toast.LENGTH_LONG).show();
	    	 }
	     }
	     
	     protected void onPreExecute () {//在 doInBackground(Params...)之前被调用,在ui线程执行
	    	 mImageView.setImageBitmap(null);
	    	 mProgressBar.setProgress(0);//进度条复位
	     }
	     
	     protected void onCancelled () {//在ui线程执行
	    	 mProgressBar.setProgress(0);//进度条复位
	     }
    	
    }
}

分析:
在分析实现流程之前,我们先了解一下AsyncTask有哪些成员变量。
  1.   private static final int CORE_POOL_SIZE = 5;//5个核心工作线程   
  2.   private static final int MAXIMUM_POOL_SIZE = 128;//最多有128个工作线程   
  3.   private static final int KEEP_ALIVE = 1;//空闲线程的超时时间为1秒   
  4.   
  5. private static final BlockingQueue<Runnable> sPoolWorkQueue =new LinkedBlockingQueue<Runnable>(10);//等待队列          
  6. public static final Executor THREAD_POOL_EXECUTOR= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);//线程池是静态变量,所有的异步任务都会放到这个线程池的工作线程内执行。  
    private static final int CORE_POOL_SIZE = 5;//5个核心工作线程
    private static final int MAXIMUM_POOL_SIZE = 128;//最多有128个工作线程
    private static final int KEEP_ALIVE = 1;//空闲线程的超时时间为1秒

  private static final BlockingQueue<Runnable> sPoolWorkQueue =new LinkedBlockingQueue<Runnable>(10);//等待队列       
  public static final Executor THREAD_POOL_EXECUTOR= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);//线程池是静态变量,所有的异步任务都会放到这个线程池的工作线程内执行。
回到例子中,点击按钮之后会新建一个GetCSDNLogoTask对象:
  1. GetCSDNLogoTask task = new GetCSDNLogoTask();    
GetCSDNLogoTask task = new GetCSDNLogoTask();  

此时会调用父类AsyncTask的构造函数:

AsyncTask.java

  1. /** 
  2.      * Creates a new asynchronous task. This constructor must be invoked on the UI thread. 
  3.      */  
  4.     public AsyncTask() {  
  5.         mWorker = new WorkerRunnable<Params, Result>() {  
  6.             public Result call() throws Exception {  
  7.                 mTaskInvoked.set(true);  
  8.   
  9.                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  
  10.                 //noinspection unchecked   
  11.                 return postResult(doInBackground(mParams));  
  12.             }  
  13.         };  
  14.   
  15.         mFuture = new FutureTask<Result>(mWorker) {  
  16.             @Override  
  17.             protected void done() {  
  18.                 try {  
  19.                     postResultIfNotInvoked(get());  
  20.                 } catch (InterruptedException e) {  
  21.                     android.util.Log.w(LOG_TAG, e);  
  22.                 } catch (ExecutionException e) {  
  23.                     throw new RuntimeException("An error occured while executing doInBackground()",  
  24.                             e.getCause());  
  25.                 } catch (CancellationException e) {  
  26.                     postResultIfNotInvoked(null);  
  27.                 }  
  28.             }  
  29.         };  
  30.     }                                                                                                                  private void postResultIfNotInvoked(Result result) {  
  31.         final boolean wasTaskInvoked = mTaskInvoked.get();  
  32.         if (!wasTaskInvoked) {  
  33.             postResult(result);  
  34.         }  
  35.     }  
  36.   
  37.   
  38.     private Result postResult(Result result) {  
  39.         @SuppressWarnings("unchecked")  
  40.         Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,  
  41.                 new AsyncTaskResult<Result>(this, result));  
  42.         message.sendToTarget();  
  43.         return result;  
  44.     }  
/**
     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
     */
    public AsyncTask() {
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);

                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
                return postResult(doInBackground(mParams));
            }
        };

        mFuture = new FutureTask<Result>(mWorker) {
            @Override
            protected void done() {
                try {
                    postResultIfNotInvoked(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) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }                                                                                                                  private void postResultIfNotInvoked(Result result) {
        final boolean wasTaskInvoked = mTaskInvoked.get();
        if (!wasTaskInvoked) {
            postResult(result);
        }
    }


    private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }

WorkerRunnable类实现了callable接口的call()方法,该函数会调用我们在AsyncTask子类中实现的doInBackground(mParams)方法,由此可见,WorkerRunnable封装了我们要执行的异步任务。FutureTask中的protected void done() {}方法实现了异步任务状态改变后的操作。当异步任务被取消,会向UI线程传递MESSAGE_POST_CANCEL消息,当任务成功执行,会向UI线程传递MESSAGE_POST_RESULT消息,并把执行结果传递到UI线程。

由此可知,AsyncTask在构造的时候已经定义好要异步执行的方法doInBackground(mParams)和任务状态变化后的操作(包括失败和成功)。

当创建完GetCSDNLogoTask对象后,执行

  1. task.execute("http://csdnimg.cn/www/images/csdnindex_logo.gif");   
task.execute("http://csdnimg.cn/www/images/csdnindex_logo.gif"); 
此时会调用AsyncTask的execute(Params...params)方法
AsyncTask.java
  1. public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,  
  2.             Params... params) {  
  3.         if (mStatus != Status.PENDING) {  
  4.             switch (mStatus) {  
  5.                 case RUNNING:  
  6.                     throw new IllegalStateException("Cannot execute task:"  
  7.                             + " the task is already running.");  
  8.                 case FINISHED:  
  9.                     throw new IllegalStateException("Cannot execute task:"  
  10.                             + " the task has already been executed "  
  11.                             + "(a task can be executed only once)");  
  12.             }  
  13.         }  
  14.   
  15.         mStatus = Status.RUNNING;  
  16.   
  17.         onPreExecute();<SPAN style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17.27px; BACKGROUND-COLOR: rgb(248,248,248); MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, mono, serif; COLOR: rgb(0,130,0); FONT-SIZE: 11.81px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px" class=comment>//运行在ui线程,在提交任务到线程池之前执行</SPAN><SPAN style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17.27px; BACKGROUND-COLOR: rgb(248,248,248); MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, mono, serif; FONT-SIZE: 11.81px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px"> </SPAN>   
  18.   
  19.         mWorker.mParams = params;  
  20.         exec.execute(mFuture);<SPAN style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17.27px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, mono, serif; COLOR: rgb(0,130,0); FONT-SIZE: 11.81px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px" class=comment>//提交任务到线程池</SPAN><SPAN style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17.27px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, mono, serif; FONT-SIZE: 11.81px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px"> </SPAN>   
  21.         return this;  
  22.     }  
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
            Params... params) {
        if (mStatus != Status.PENDING) {
            switch (mStatus) {
                case 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)");
            }
        }

        mStatus = Status.RUNNING;

        onPreExecute();<span><span class="comment" style="font-family:Consolas, 'Courier New', Courier, mono, serif;color:#0820;BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; BACKGROUND-COLOR: rgb(248,248,248); MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-SIZE: 11px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px">//运行在ui线程,在提交任务到线程池之前执行</span><span style="font-family:Consolas, 'Courier New', Courier, mono, serif;BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; BACKGROUND-COLOR: rgb(248,248,248); MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-SIZE: 11px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px"> </span></span>

        mWorker.mParams = params;
        exec.execute(mFuture);<span><span class="comment" style="font-family:Consolas, 'Courier New', Courier, mono, serif;color:#0820;BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-SIZE: 11px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px">//提交任务到线程池</span><span style="font-family:Consolas, 'Courier New', Courier, mono, serif;BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-SIZE: 11px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px"> </span></span>
        return this;
    }

当任务正在执行或者已经完成,会抛出IllegalStateException,由此可知我们不能够重复调用execute(Params...params)方法。在提交任务到线程池之前,调用了onPreExecute()方法。然后才执行sExecutor.execute(mFuture)是任务提交到线程池
前面我们说到,当任务的状态发生改变时(1、执行成功2、取消执行3、进度更新),工作线程会向UI线程的Handler传递消息。在《Handler+Looper+MessageQueue深入详解》一文中我们提到,Handler要处理其他线程传递过来的消息。在AsyncTask中,InternalHandler是在UI线程上创建的,它接收来自工作线程的消息,实现代码如下:
AsyncTask.java
  1.  private static class InternalHandler extends Handler {  
  2.         @SuppressWarnings({"unchecked""RawUseOfParameterizedType"})  
  3.         @Override  
  4.         public void handleMessage(Message msg) {  
  5.             AsyncTaskResult result = (AsyncTaskResult) msg.obj;  
  6.             switch (msg.what) {  
  7.                 case MESSAGE_POST_RESULT:  
  8.                     // There is only one result   
  9.                     result.mTask.finish(result.mData[0]);<SPAN style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17.27px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, mono, serif; COLOR: rgb(0,130,0); FONT-SIZE: 11.81px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px" class=comment>//执行任务成功</SPAN><SPAN style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17.27px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, mono, serif; FONT-SIZE: 11.81px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px">  </SPAN>   
  10.                     break;  
  11.                 case MESSAGE_POST_PROGRESS:  
  12.                     result.mTask.onProgressUpdate(result.mData);<SPAN style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17.27px; BACKGROUND-COLOR: rgb(248,248,248); MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, mono, serif; COLOR: rgb(0,130,0); FONT-SIZE: 11.81px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px" class=comment>//进度更新</SPAN><SPAN style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17.27px; BACKGROUND-COLOR: rgb(248,248,248); MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-FAMILY: Consolas, 'Courier New', Courier, mono, serif; FONT-SIZE: 11.81px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px">  </SPAN>   
  13.                     break;  
  14.             }  
  15.         }  
  16.     }  
 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
                    result.mTask.finish(result.mData[0]);<span><span class="comment" style="font-family:Consolas, 'Courier New', Courier, mono, serif;color:#0820;BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-SIZE: 11px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px">//执行任务成功</span><span style="font-family:Consolas, 'Courier New', Courier, mono, serif;BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-SIZE: 11px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px">  </span></span>
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);<span><span class="comment" style="font-family:Consolas, 'Courier New', Courier, mono, serif;color:#0820;BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; BACKGROUND-COLOR: rgb(248,248,248); MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-SIZE: 11px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px">//进度更新</span><span style="font-family:Consolas, 'Courier New', Courier, mono, serif;BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 17px; BACKGROUND-COLOR: rgb(248,248,248); MARGIN: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; FONT-SIZE: 11px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 0px">  </span></span>
                    break;
            }
        }
    }

当接收到消息之后,AsyncTask会调用自身相应的回调方法。

总结:

1、 AsyncTask的本质是一个静态的线程池,AsyncTask派生出的子类可以实现不同的异步任务,这些任务都是提交到静态的线程池中执行。

2、线程池中的工作线程执行doInBackground(mParams)方法执行异步任务

3、当任务状态改变之后,工作线程会向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关的回调函数

转载博文地址:http://blog.csdn.net/mylzc/article/details/6774131

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值