Android开发:AsyncTask源码解析


关于AsyncTask的使用可以参看Android sdk提供的AsyncTask相关文档,本文来解析AsyncTask的源代码。

我们只需要调用AsyncTask的execute方法,因此我们也将从这里开始。

  1. public final AsyncTask<Params, Progress, Result> execute(Params... params) {  
  2.         if (mStatus != Status.PENDING) {//Status有PENDING(未执行),RUNNING(正在执行),FINISHED(已完成)三个状态,如果mStatus不为PENDING,则抛出异常   
  3.             switch (mStatus) {  
  4.                 case RUNNING:  
  5.                     throw new IllegalStateException("Cannot execute task:"  
  6.                             + " the task is already running.");  
  7.                 case FINISHED:  
  8.                     throw new IllegalStateException("Cannot execute task:"  
  9.                             + " the task has already been executed "  
  10.                             + "(a task can be executed only once)");  
  11.             }  
  12.         }  
  13.   
  14.         mStatus = Status.RUNNING;//从PENDING状态转为RUNNING,所以当AsyncTask只能调用一次execute,第二次调用时mStatus为RUNNING就会抛出异常   
  15.   
  16.         onPreExecute();//由UI线程在执行doInBackground方法之前执行   
  17.   
  18.         mWorker.mParams = params;//mWorker为WorkerRunnable类型,WorkerRunnable是AsyncTask的一个抽象静态内部类,该类继承了Callable接口,并且拥有Params[] mParams做为其成员   
  19.         sExecutor.execute(mFuture);//mFuture为FutureTask类型,该类实现Future<V>, Runnable接口,sExecutor是一个ThreadPoolExecutor类型   
  20.   
  21.         return this;  
  22.     }  
当执行sExecutor.execute(mFuture)时,调用了ThreadPoolExecutor中的execute方法,该方法使用一个Runnable作为参数,如下:
  1. public void execute(Runnable command) {  
  2.          ......  
  3.         int c = ctl.get();  
  4.         if (workerCountOf(c) < corePoolSize) {  
  5.             if (addWorker(command, true))  
  6.                 return;  
  7.             c = ctl.get();  
  8.         }  
  9.           ......  
  10.     }  
其中addWorker方法会把传进来的Runnable对象放入其工作队列中,并执行该Runnable,如下:
  1. private boolean addWorker(Runnable firstTask, boolean core) {  
  2.         .....  
  3.         Worker w = new Worker(firstTask);  
  4.         Thread t = w.thread;  
  5.         final ReentrantLock mainLock = this.mainLock;//获得线程锁   
  6.         mainLock.lock();//锁住线程   
  7.         try {  
  8.             int c = ctl.get();  
  9.             int rs = runStateOf(c);  
  10.   
  11.             if (t == null ||  
  12.                 (rs >= SHUTDOWN &&  
  13.                  ! (rs == SHUTDOWN &&  
  14.                     firstTask == null))) {  
  15.                 decrementWorkerCount();  
  16.                 tryTerminate();  
  17.                 return false;  
  18.             }  
  19.   
  20.             workers.add(w);//放入工作队列   
  21.   
  22.             int s = workers.size();  
  23.             if (s > largestPoolSize)  
  24.                 largestPoolSize = s;  
  25.         } finally {  
  26.             mainLock.unlock();//开锁   
  27.         }  
  28.   
  29.         t.start();//执行线程,关键   
  30.         ...  
  31.         return true;  
  32.     }  
 
  1. 到此我们知道AsyncTask的execute的执行流程为  
  2. 先调用ThreadPoolExecutor.execute(mFuture);  
  3. 然后ThreadPoolExecutor.execute(mFuture) 会调用ThreadPoolExecutor.addWorker(mFuture);  
  4. 最后ThreadPoolExecutor.addWorker(mFuture)会调用mFuture的run()方法,run方法中就是该线程要执行操作的地方  
  5. 到此我们来关注一下mFuture,AsyncTask中的mFuture是一个FutureTask,FutureTask实现了Future<V>, Runnable两个接口,  
  6. Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果,计算完成后只能使用 get 方法来获取结果。  
  7. mFuture以mWorker作为参数  
  1.  mFuture = new FutureTask<Result>(mWorker) {  
  2.      。。。。  
  3. }  

用到了FutureTask的一个构造函数

  1. public FutureTask(Callable<V> callable) {  
  2.         if (callable == null)  
  3.             throw new NullPointerException();  
  4.         sync = new Sync(callable);  
  5.     }  
sync为Sync类,Sync类为FutureTask的内部类,该类是AbstractQueuedSynchronizer类的子类
  1. private final class Sync extends AbstractQueuedSynchronizer{  
  2.     ...  
  3. }  
因此我们知道mWorker是一个实现了callable接口的类,并且持有Params[] mParams参数
  1. private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {  
  2.    Params[] mParams;  
  3. }  
我们再来看看FutureTask的run方法
  1. public void run() {  
  2.      sync.innerRun();  
  3.  }  
调用了sync的innerRun()方法。
  1. void innerRun() {  
  2.     ...  
  3.         runner = Thread.currentThread();  
  4.         if (getState() == RUNNING) { // recheck after setting thread   
  5.             V result;  
  6.             try {  
  7.                 result = callable.call();//调用callable的call方法并返回值,此时的callable为mWorker   
  8.             } catch (Throwable ex) {  
  9.                 setException(ex);  
  10.                 return;  
  11.             }  
  12.             set(result);//设置结果   
  13.         } else {  
  14.             releaseShared(0); // cancel   
  15.         }  
  16.     }  
innerRun方法中调用了callable的call方法,该callable在这里就是mWorker,我们来看看mWorker的call方法
  1. mWorker = new WorkerRunnable<Params, Result>() {  
  2.     public Result call() throws Exception {  
  3.         Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  
  4.         return doInBackground(mParams);  
  5.     }  
  6. };  
  • 1
  • 2
  • 3
  • 下一页

相关内容