自10年大量看源码后,很少看了,抽时间把最新的源码看看! public abstract class AsyncTask<Params, Progress, Result> { 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 = 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); 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 final WorkerRunnable<Params, Result> mWorker; private final FutureTask<Result> mFuture; private volatile Status mStatus = Status.PENDING; /** * Indicates the current status of the task. Each status will be set only once * during the lifetime of a task. */ 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, } /** * 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 { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); return doInBackground(mParams); } }; 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(); } }; } /** * Returns the current status of this task. * * @return The current status. */ public final Status getStatus() { return mStatus; } protected abstract Result doInBackground(Params... params); protected void onPreExecute() { } @SuppressWarnings({"UnusedDeclaration"}) protected void onPostExecute(Result result) { } @SuppressWarnings({"UnusedDeclaration"}) protected void onProgressUpdate(Progress... values) { } protected void onCancelled() { } public final boolean isCancelled() { return mFuture.isCancelled(); } public final boolean cancel(boolean mayInterruptIfRunning) { return mFuture.cancel(mayInterruptIfRunning); } 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) { 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(); mWorker.mParams = params; sExecutor.execute(mFuture); return this; } protected final void publishProgress(Progress... values) { sHandler.obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } private void finish(Result result) { onPostExecute(result); mStatus = Status.FINISHED; } 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; case MESSAGE_POST_CANCEL: result.mTask.onCancelled(); break; } } } 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的全部代码。 ----------------------------------------------------------------- AsyncTask多用于Android的Context(Activity)处理后台逻辑同时又要兼顾主线程的一些逻辑(比如说Activity的UI更新)。 AsyncTask它其实是封装了一个多线程、向开发者屏蔽了考虑多线程的问题。开发人员只需去重写AsyncTask中的doInBackground、onProgressUpdate、onPreExecute、onPostExecute等方法,然后生成该对象并执行execute方法即可实现异步操作。 由于Android负责Context(Activity)的主线程(或者说是UI控制线程)不是线程安全的,也就是说开发者不能在自己生成的线程对象里面操作Activity的UI更新。 对于习惯了Java开发的开发人员来说,非要自己生成线程对象,在这个线程里操作一些时间较长的逻辑(比如下载文件),完成之后再提醒用户下载完成(UI更新,比如在一个TextView中把文字修改成"下载完成")的话,那么UI更新的工作只能借助于Handler(这个Handler必须是在主线程中生成,或者说和主线程共用一个Looper和MessageQueue,通常的方法是在Activity中的onCreate方法中生成重写的Handler对象)。当开发者的线程完成逻辑操作之后,发送一个消息到Handler,再由Handler去处理。如果Handler由主线程生成,那么这个Handler的handleMessage()会在主线程中执行,因此在handleMessage()中可以访问Activity中的某个View并修改。如一下代码: public class TestActivity extends Activity{ private static final int WHAT = 0x01;<br> private Thread downloadThread; private Handler refleshHandler; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.main); super.onCreate(savedInstanceState); downloadThread = new Thread(new DownloadRunnable()); refleshHandler = new RefleshHandler(); downloadThread.start(); } private class DownloadRunnable implements Runnable { public void run() { System.out.println("开始处理业务"); //耗时较长的逻辑代码省略 refleshHandler.sendEmptyMessage(WHAT); } } private class RefleshHanler extends Handler{ @Override public void handleMessage(Message msg) { if(msg.what == WHAT){ //更新TestActivity UI } } } 上述的方法也未尝不是一种好的方法。然而Android为开发者提供了一种新的解决方案,那就是AsyncTask,分析完源代码会发现,其实AsyncTask为我们封装了上述的方法。 对于我们重写AsyncTask的doInBackground()的方法,AsyncTask会将它封装成一个实现Callable接口的对象,在线程池中找出一个线程是实现它,因此我们所需要的耗时较长的逻辑可以放在这个方法里面。 AsyncTask也维护着一个静态的Handler,这个Handler属于创建AsyncTask的线程,而创建AsyncTask一般都是主线程(UI线程),因此这个Handler可以访问并Activity的UI。 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; case MESSAGE_POST_CANCEL: result.mTask.onCancelled(); break; } } } 可以看到这个Handler操作了AsyncTask的三个方法:finish() , onProgressUpdate() , onCancelled(),而finish() 又调用onPostExecute()方法。 可以这么说,onProgressUpdate() ,onCancelled(),onPostExecute() 用来被开发者重写,去更新UI的,这3个方法会涉及到UI的操作,因此doInBackground()方法里不能调用这几个方法,也就是说开发者可以重写这些方法,但是又不能直接调用这些方法,只能通过发送消息给Handler的方式来隐式的调用。 onProgressUpdate()是一个更新处理进度的方法,开发者可以重写它,可以将它关联到Activity的一个进度条控件上,在doInBackground()里可以用publishProgress()去间接调用它(其实这个函数也是通过发送what为MESSAGE_POST_PROGRESS的Message给Handler的方式来调用onProgressUpdate()的),这样就能在UI上显示进度信息。 finish()方法,也就是onPostExecute(),是处理完doInBackground()得到结果之后的调用。doInBackground()的函数封装在实现Callable接口的名叫一个WorkerRunnable的抽象类中,再将这个类封装在Future中,并重写Future的done()方法,这个方法会在Callable的call方法执行完之后调用,就是doInBackground()方法执行完之后调用,它可以获得执行完的结果,Future.get()方法(可能阻塞),并将得到的结果封装在what为MESSAGE_POST_RESULT的Message中,并发送。上诉的核心代码如下: private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; } mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); return doInBackground(mParams); } }; 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(); } }; 同理,onCancelled()是在AsyncTask被取消时的调用,也是通过Handler的方法。 有一点要注意到,还有一个onPreExecute()方法,虽然这个方法是未被Handler加入到消息处理的方法里,但是这个方法是在execute()里执行的,execute是主线程(UI线程)才会去执行的,所以这个方法也能访问和修改UI。 总结: 开发者可以重写AsyncTask的onProgressUpdate() , onCancelled(), onPostExecute(), onPreExecute(), doInBackground()方法,以得到异步实现后台逻辑并更新UI的操作。 其中onProgressUpdate() , onCancelled(), onPostExecute(), onPreExecute() 可以直接访问并修改UI。 但是doInBackground()不能出现涉及UI的操作,也不能直接调用onProgressUpdate() , onCancelled(), onPostExecute(), onPreExecute() 这四个方法,后三者不需要调用,可以通过publishProgress()去间接的调用onProgressUpdate()方法。 最后要说的是AsyncTask的对象一旦生成之后,execute()方法只能被调用一次,即使是同样的操作,也需要重新生成AsyncTask对象才行。