两个线程池:ThreadPoolExecutor (THREAD_POOL_EXECUTOR) SerialExecutor(SERIAL_EXECUTOR, sDefaultExecutor)
一个Handler: internalHandler
THREAD_POOL_EXECUTOR队列: BlockingQueue队列存放线程LinkedBlockingQueue128
sDefaultExecutor队列: ArrayDeque队列, 默认大小
//Queue接口
public abstract boolean add(E paramE);
public abstract boolean offer(E paramE);
public abstract E remove();
public abstract E poll();
Queue接口提供了以上几个方法。
看了ArrayDeque类的源码。有以下几点总结:
1)ArrayDeque有两个类属性,head和tail,两个指针。
2)ArrayDeque通过一个数组作为载体,其中的数组元素在add等方法执行时不移动,发生变化的只是head和tail指针,而且指针是循环变化,数组容量不限制。
3)offer方法和add方法都是通过其中的addLast方法实现,每添加一个元素,就把元素加到数组的尾部,此时,head指针没有变化,而tail指针加一,因为指针是循环加的,所以当tail追上head((this.tail = this.tail + 1 & this.elements.length - 1) == this.head)时,数组容量翻一倍,继续执行。
4)remove方法和poll方法都是通过其中的pollFirst方法实现,每移除一个元素,该元素所在位置变成null,此时,tail指针没有变化,而head指针加一,当数组中没有数据时,返回null。
5)因为ArrayDeque不是线程安全的,所以,用作堆栈时快于 Stack,在用作队列时快于 LinkedList。
执行过程: 当调用excute(Params... params)方法之后 excute 方法调用excuteOnExcutor()方法, excuteOnExcutor()判断状态RUNNING, FINISHED并相应抛出异常, 然后调用onPreExctue()方法
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
//sDefaultExecutor----->exec
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;
//再通过传入的sDefaultExcutor即exec执行excute(),
//SericlaEcecutor 内部实现一个队列:ArrayDeque<Runnable> mTasks
//每次sDefaultDecutor即exec执行execute(mFuture)执行下面代码
exec.execute(mFuture);
return this;
}
// SericalExecutor是串行执行的
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);
}
}
}
首先AsyncTask将传进Parmas参数封装成FutureTask对象AsyncTask的成员变量mFuture, 这里的mFuture 充当Runnable, 然后mFuture交给SericalExecutor的exceute执行, mFuture的运行并不是以thread运行的, 而是SericalExector将mFuture的run放到另起一个Runnable中执行然后offer到mTasks中并执行scheduleNext()来执行THREAD_POOL_EXECUTOR.execute()也就是把mTasks中的pop出一个Runnable拿出来运行, 来实现串行机制.
mFutureTask的run方法会调用mWorker的call()方法, 因此mWorker的call方法最终在线程池中执行
mWorker在AsyncTask构造函数中生成, 调用call时会设置mTaskInvoked为ture, 设置进程优先级为Process.THREAD_PRIORITY_BACKGROUND, 调用doInBackground()返回result传给postRuselt()
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
postResult()方法通过sHandler发送一个MESSAGE_POST_RESULT sHandler则调用result.mTask.finish(result.mData[0])
InternalHandler的实现
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;
}
}
}
InternalHandler sHandler是一个静态的handler在AsyncTask里面只存在一个, 为了能切换到UI线程, 因此需要它在UI线程里初始化, 也就是AsyncTask实例需要在UI线程里初始化.
这里看到还有个Message是MESSAGE_POST_PROGRESS
就是我在重写doInBackground执行耗时任务的时候每走一步发送一个进度publishProgress()调用
@WorkerThread
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
进行更新UI进度的.
完成分析