public abstract class AsyncTask<Params, Progress, Result> { //日志TAG private static final String LOG_TAG = "AsyncTask"; //池中所保存的线程数,包括空闲线程。 private static final int CORE_POOL_SIZE = 5; //池中允许的最大线程数。 private static final int MAXIMUM_POOL_SIZE = 128; //当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。 private static final int KEEP_ALIVE = 1; //一个线程工厂,用来创建新线程 没啥好说的。 private static final ThreadFactory sThreadFactory = new ThreadFactory() { //这个类是一个线程安全的计数器,用到Unsafe直接与底层打交道。 private final AtomicInteger mCount = new AtomicInteger(1); //接口实现的方法,就是给线程起了个名字。 public Thread newThread(Runnable r) { return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } }; //一个固定长度的LinkedBlockingQueue(队列),长度为10。 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); //创建一个实现了Executor接口的类 这个类的介绍在下面 public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); //Message的消息类型 private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; //通知主线程的Handler,细节在下面有解释 private static final InternalHandler sHandler = new InternalHandler(); //就是把上面的SERIAL_EXECUTOR拿过来了,和上面的一样 private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; //实现了Callable接口 添加了一个参数Params private final WorkerRunnable<Params, Result> mWorker; //封装具体的任务,这个类的细节可以单独研究 这里也不做细说。 //这个类的特点就是可以取消并且可以监控任务状态 private final FutureTask<Result> mFuture; //将状态设置成【还没开始执行】的状态 private volatile Status mStatus = Status.PENDING; //标记任务是否已经取消,后面的一些方法需要用到。 private final AtomicBoolean mCancelled = new AtomicBoolean(); //标记任务是否已经执行,后面的一些方法需要用到。 private final AtomicBoolean mTaskInvoked = new AtomicBoolean(); //实现Executor接口 对Runnable(任务)在进行一次封装 //这样的实现可以使任务保持连续,即第一个任务执行完毕接着会执行第二个任务 //第二个任务执行在执行第三个任务,以此类推。 private static class SerialExecutor implements Executor { //一个数组双端队列没有容量限制 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); //当前正在执行的任务 Runnable mActive; //这里进行了synchronized,因为ArrayDeque不是线程安全的,对它的操作需要同步。 public synchronized void execute(final Runnable r) { //对任务进行包装,然后加入队列的末尾。 mTasks.offer(new Runnable() { public void run() { try { //执行具体任务 r.run(); } finally { //执行下一个任务【编号001】 scheduleNext(); } } }); //如果当前没有执行的任务,则调用scheduleNext开始执行任务 //如果不为null 说明已经有任务在执行,那么就不需要调用scheduleNext //因为当前任务会被上一个任务在完成时调用。即在【编号001】的位置。 if (mActive == null) { scheduleNext(); } } //从队列的头部拿出一个元素,然后执行。这里的任务是在上面包装过的。 //它会先执行具体任务,然后再执行下一个任务 protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } } //当前类的状态 public enum Status { //还没开始执行 PENDING, //执行中 RUNNING, //任务完成 FINISHED, } //没啥用 public static void init() { sHandler.getLooper(); } //没啥用 public static void setDefaultExecutor(Executor exec) { sDefaultExecutor = exec; } //构造参数必须运行在UI线程 public AsyncTask() { //创建一个WorkerRunnable实例 //这里用到了FutureTask与Callable相关技术。需要自己去研究下 mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { //一旦具体任务执行,就将这个标记置为true mTaskInvoked.set(true);//【编号002】 //设置当前线程优先级为后台线程 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //首先调用doInBackground这个方法 就是我们需要复写的方法。 //然后调用postResult方法 并将doInBackground的返回值传入。 return postResult(doInBackground(mParams)); } }; //创建一个任务FutureTask,并将上面的mWorker通过构造参数传入。 mFuture = new FutureTask<Result>(mWorker) { //覆写了done方法,这样当任务的状态发生变化时可以进行监控。 //当任务完成时或取消都进入该方法 @Override protected void done() { try { //通过get方法获取任务的返回结果 //下面就分2中情况 //1-如果上面的call方法正确被调用 那么就执行postResultIfNotInvoked方法 //2-如果任务被取消或者任务执行过程中出现异常则会抛出异常,在下面catch到在进行处理 postResultIfNotInvoked(get()); } catch (InterruptedException e) { android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) { //如果在doInBackground方法中存在异常 这里会继续抛出 throw new RuntimeException("An error occured while executing doInBackground()", e.getCause()); } catch (CancellationException e) { //如果方法被取消,那么调用postResultIfNotInvoked并传入null postResultIfNotInvoked(null); } } }; } private void postResultIfNotInvoked(Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); //这里判断wasTaskInvoked标记,判断任务是否已经正常结束 //如果在mWorker的call方法正确执行 那么在【编号002】的位置会把wasTaskInvoked设置为true //这样的话在done()方法中的postResultIfNotInvoked(get());方法才不会重复执行 //也就是说方法如果在mWorker的call方法中执行了 那么在done()中在调用postResultIfNotInvoked(get()); //方法在执行到这的话就不会执行了,反之亦然。 if (!wasTaskInvoked) { postResult(result); } } //该方法是把任务结果发送给UI线程去执行 //就是Looper Handler Message 没啥好说的 private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; } //过去当前任务的执行状态 public final Status getStatus() { return mStatus; } //需要子类付覆写的方法,后台线程运行。 protected abstract Result doInBackground(Params... params); //在doInBackground方法执行运行,UI线程运行该方法。 //可以启动个进度条之类的操作可以写在这里。 protected void onPreExecute() { } //UI线程执行,在doInBackground放执行以后执行。 //要注意的是在任务没有出现异常 也没有被取消的情况下才会执行 //否则执行onCancelled @SuppressWarnings({"UnusedDeclaration"}) protected void onPostExecute(Result result) { } //运行在UI线程 通过在doInBackground中调用publishProgress方法通知UI线程做一些处理 //比如更新带百分比的进度条等 @SuppressWarnings({"UnusedDeclaration"}) protected void onProgressUpdate(Progress... values) { } @SuppressWarnings({"UnusedParameters"}) protected void onCancelled(Result result) { onCancelled(); } //一般子类覆写这个方法 就是cancel方法被调用后 任务被取消 则会执行该方法 protected void onCancelled() { } //获取任务是否取消 public final boolean isCancelled() { return mCancelled.get(); } //终止任务 //参数的意义是这样的 //如果线程还没有被启动,那么无论mayInterruptIfRunning是啥 任务都会被取消 //如果任务已经启动 那么如果mayInterruptIfRunning=true 那么会调用线程的 //interrupt方法,这个方法是的解释可以看API 太多了 这里不细说。 public final boolean cancel(boolean mayInterruptIfRunning) { mCancelled.set(true); return mFuture.cancel(mayInterruptIfRunning); } //这个方法获取任务的结果,是一个阻塞方法 //属于FutureTask的范畴 public final Result get() throws InterruptedException, ExecutionException { return mFuture.get(); } //同上 public final Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return mFuture.get(timeout, unit); } //启动任务 public final AsyncTask<Params, Progress, Result> execute(Params... params) { //调用executeOnExecutor return executeOnExecutor(sDefaultExecutor, params); } //这个方法是AsyncTask的启动方法,用来启动任务 public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { //判断任务的状态 如果不是PENDING状态则抛出异常 //也就是说任务只能启动一次,不可重复启动。 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)"); } } //设置任务状态为RUNNING mStatus = Status.RUNNING; //调用预处理方法上面解释过。 onPreExecute(); //给mWorker设置参数 mWorker.mParams = params; //将任务加入到sDefaultExecutor当中去执行 exec.execute(mFuture); //返回自己 return this; } //这个方法是用过sDefaultExecutor执行直接执行一个Runnable接口,去AsyncTask没啥关系 //无非就是用到了sDefaultExecutor public static void execute(Runnable runnable) { sDefaultExecutor.execute(runnable); } //这个方法可以通知UI线程更新进度 protected final void publishProgress(Progress... values) { if (!isCancelled()) { sHandler.obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } } //任务完成后调用的方法,会根据isCancelled()的返回值判断任务是否被取消或者正常执行成功。 private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; } //Handler没啥好说的 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]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } } } //一个抽象类实现了Callable<Result>接口 添加了参数。 private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; } //一个用于封装任务与结果的类 @SuppressWarnings({"RawUseOfParameterizedType"}) private static class AsyncTaskResult<Data> { final AsyncTask mTask; final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } } }
AsyncTask 核心原理大概如下
InternalHandler sHandler = new InternalHandler(); 这个handler是主线程初始化的,用来调用更新UI的方法。
THREAD_POOL_EXECUTOR 一个线程池用来处理异步任务。
sPoolWorkQueue 一个任务队列,我们发起的所有任务都会放到这个队列当中,由THREAD_POOL_EXECUTOR 它来进行处理。
流程就是当我们创建一个AsyncTask实例 ,那么AsyncTask会生成一个任务对象(Runnable)放入sPoolWorkQueue 这个队列当中,然后有THREAD_POOL_EXECUTOR 线程池去进行异步处理,在处理的过程中通过sHandler 通知主线程去调用我们复写的那几个方法更新UI。
这个类在设计当中还使用到了 FutureTask
关于这个类的源码分析请看我的另外一个博客:http://www.cnblogs.com/daxin/p/3802392.html