最近 一直在看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);
}
}
};
}