1.
http://developer.android.com/reference/android/os/AsyncTask.html
2.
http://blog.csdn.net/pi9nc/article/details/12622797
3.
http://www.tuicool.com/articles/VnMf2i3
下面详细解析Asynctask的源码流程。我们在阅读源码的时候需要知道的重要点是:输入输出(参数)、以及程序入口(什么地方进入调用)。
/** * Override this method to perform a computation on a background thread. The * specified parameters are the parameters passed to {@link #execute} * by the caller of this task.参数为传给execute的方法参数 看方法名称此方法在非主线程中调用 * * This method can call {@link #publishProgress} to publish updates * on the UI thread. * * @param params The parameters of the task. 任务参数如不同的URL等 * * @return A result, defined by the subclass of this task. 结果 * */ protected abstract Result doInBackground(Params... params); /** * Runs on the UI thread before {@link #doInBackground}. * 运行在UI线程 在调用doInBackground */ protected void onPreExecute() { } /** * <p>Runs on the UI thread after {@link #doInBackground}. The * specified result is the value returned by {@link #doInBackground}.</p> * * <p>This method won't be invoked if the task was cancelled.</p> * * @param result The result of the operation computed by {@link #doInBackground}. */ @SuppressWarnings({"UnusedDeclaration"}) protected void onPostExecute(Result result) { } /** * Runs on the UI thread after {@link #publishProgress} is invoked. * The specified values are the values passed to {@link #publishProgress}. * * @param values The values indicating progress.泛型参数为进度条 * */ @SuppressWarnings({"UnusedDeclaration"}) protected void onProgressUpdate(Progress... values) { }
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }一句话又开始跳转:
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(); mWorker.mParams = params; exec.execute(mFuture); return this; }3-13行是检查任务启动是否合理 17行调用:
onPreExecute();明显该方法在主线程调用。19行更新mWorker参数(实现此为callable接口的对象 后面会提到)。20行为
exec.execute(mFuture);看又开始跳转。exec为传输的参数:
sDefaultExecutor故接着跳入:
public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } }mTask为ArrayDeque为Runnable 数组双端队列。但同时存在线程不安全性 故方法名前添加synchronized关键字。mTask.offer 每添加一个元素,就把元素加到数组的尾部。这里每次回去创建一个线程。在线程run方法中执行r.run。重点来了r是之前提到的mFutrue。查找下源码的该成员变量。
private final FutureTask<Result> mFuture; 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); } } }; }我们先看FutrueTask是个什么东东 如果对多线程很熟悉的童鞋不会陌生。FutureTask是一个RunnableFuture<V>,而RunnableFuture实现了Runnbale又实现了Futrue<V>这两个接口。
public class FutureTask<V> implements RunnableFuture<V> public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run(); }此处源码码mFuture = new FutureTask<Result>(mWorker) 调用的是
public FutureTask(Callable<V> callable)
mWorker实现callable方法。具体mFuture如何调用callable方法参见: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)); } };有人会奇怪 mWork怎么会实现了callable方法?看此处:
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }callable接口与runnable很相似。不过最大好处在于callable接口的call方法有返回值。回到mWorker的call方法中。返回了postResult(doInBackground(mParams)) 这里先是调用了我们的doInBackground(mParams)显然此处在非主线程 故可以处理耗时任务 最后通过postResult返回结果
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }我们发现熟悉的了 通过sHandler来处理消息。
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; } } }
private static class AsyncTaskResult<Data> { final AsyncTask mTask; final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } }
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }这里判断任务 是否被cancelled 否的话调用onPostExecute(result); 是的话调用 onCancelled(result);并更新状态。此处完成。 回到handleMessage MESSAGE_POST_PROGRESS是什么谁发出的呢?
protected final void publishProgress(Progress... values) { if (!isCancelled()) { sHandler.obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } }那什么时候调用的呢?使用过AsyncTask的童鞋会记得。我们会在doInbackgroud方法中调用 publishProgress()方法。整个asyncTask方法阅读完成。但有些坑。比如为什么采用线程池+FutureTask方式。又比如
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);此处线程池的个数与之前3.0 版本AsyncTask设置不一样。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/nothingl3/article/details/48086269