最近 一直在看android多线程部分的源码 突然想到android中的 异步任务类 AsyncTask类 于是便看了看 它的源码 下面我就针对它的源码 分析一下它执行的过程:
首先我们先看看这个类的成员变量
private static final String LOG_TAG = "AsyncTask"; private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); //获取处理器的个数 private static final int CORE_POOL_SIZE = CPU_COUNT + 1; //线程核心池的大小 用于初始化 线程池 对象时使用 private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; // 同上 private static final int KEEP_ALIVE = 1; 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 BlockingQueue<Runnable> sPoolWorkQueue = //阻塞队列 这里使用的是 链式的阻塞队列 new LinkedBlockingQueue<Runnable>(128); /** * An {@link Executor} that can be used to execute tasks in parallel. */ public static final Executor THREAD_POOL_EXECUTOR //线程池对象 = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); /** * An {@link Executor} that executes tasks one at a time in serial * order. This serialization is global to a particular process. */ public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); //任务执行器 具体实现在下面说明 用于执行异步任务 private static final int MESSAGE_POST_RESULT = 0x1; //任务执行结束 private static final int MESSAGE_POST_PROGRESS = 0x2; //任务执行中 这两个变量用于在handler中 接受消息并执行相应代码 private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; //任务执行器 private static InternalHandler sHandler; // handler对象 里面有处理<span style="font-family: Arial, Helvetica, sans-serif;">MESSAGE_POST_RESULT MESSAGE_POST_PROGRESS 的逻辑</span> private final WorkerRunnable<Params, Result> mWorker; // 此类 集成 Callable接口 类似于 Runnable的作用 private final FutureTask<Result> mFuture; //用于封装 mWorker 使之可以返回线程执行结果 private volatile Status mStatus = Status.PENDING; private final AtomicBoolean mCancelled = new AtomicBoolean(); //原子类型的变量 private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
在这些方法的特定位置 调用回调接口 即可
看execute方法 :
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
@MainThread 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); //执行Executor的 execute方法 其中 exec参数 是 SerialExecutor类 return this; }
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() { //向mtasks中加入runnable 对象 其中 r是个futureTask对象 封装了一个Callable 所以实际上执行的是 callable的call方法 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); } } }
其中 r是个futureTask对象 封装了一个Callable 所以实际上执行的是 callable的call方法
mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); //执行耗时任务 回调接口 Binder.flushPendingCommands(); return postResult(result); //任务执行完毕 发送消息给 handler } };
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
private static class InternalHandler extends Handler { public InternalHandler() { super(Looper.getMainLooper()); } @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 void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
这样就完成了 异步任务的调用 其实很简单 运用了线程池
最后 看看 AsyncTask的 构造函数吧
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); } }; 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 occurred while executing doInBackground()", e.getCause()); } catch (CancellationException e) { postResultIfNotInvoked(null); } } }; }