[转载]AsyncTask源码分析 – 周柯文 – 博客园.
要研究Android的AsyncTask之前,要先搞明白FutureTask和Executor类:
FutureTask是什么:
FutureTask实际上是一个任务的操作类,它并不启动新线程,只是在自己所在线程上操作,任务的具体实现是构造FutureTask时提供的,实现自Callable<V>接口,FutureTask不知道具体的任务是什么,它只知道如何调度任务,如:
- 如何启动任务:在FutureTask的run()方法中(实现自Runnable.run()),调用Callable.call()方法来启动任务,Callable.call()方法中是任务的具体实现;
- 如何取消任务:在cancel()里,中断执行任务的线程,记录任务结束状态,并调用done()方法来执行用户实现的操作;
- 如何返回任务的运行结果:如果任务还在执行,则阻塞线程(使用LockSupport.park()),直到任务结束才返回结果,用户可以通过get()方法来获取结果,同样当任务运行结束时,会调用down()来执行用户实现的操作。
使用FutureTask的好处是,更轻松的对任务进行管理,而不是像Runnable那样扔进线程后就啥也不能做了。
Executor是什么:
Executor顾名思义是任务执行者,它不关心是什么任务,只关心如何执行任务。Executor是个Interface,具体如何执行任务要看怎么实现这个接口,你可以这样实现:
class DirectExecutor implements Executor { @Override public void execute(Runnable r) { r.run(); } }
也可以这样实现:
class ThreadPerTaskExecutor implements Executor { @Override public void execute(Runnable r) { new Thread(r).start(); } }
这两种实现的区别显而易见,java文档还提供了另一个Executor实现的例子:
class SerialExecutor implements Executor {
final Queue tasks = new ArrayDeque();
final Executor executor;
Runnable active;
SerialExecutor(Executor executor) {
this.executor = executor;
}
@Override
public synchronized void execute(final Runnable r) {
tasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((active = tasks.poll()) != null) {
executor.execute(active);
}
}
}
这个实现的意思是,严格按照用户提交的顺序来执行任务。Android的AsyncTask就使用了这个例子。
AsyncTask是如何实现的:
AsyncTask实现的关键地方在构造函数和executeOnExecutor()函数里。
- 首先看下构造函数:
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//任务的具体实现
return postResult(doInBackground(mParams));
}
};
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);
}
}
};
}
代码中WorkerRunnable实现自Callable,所以mWorker就是任务的具体实现(call()中的doInBackground())。通过对FutureTask的说明可以知道,mFuture是mWorker的操作类,它不仅用来实现对AsyncTask任务的操作(cancel,get等),最主要的,实现了mWorker执行结束的操作:
private void postResultIfNotInvoked(Result result) {
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {
postResult(result);
}
}
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
private static final InternalHandler sHandler = new InternalHandler();
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 void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
FutureTask和Handler共同实现了任务结束的操作,代码很简单,不赘述。
接下来是executeOnExecutor()函数的实现:
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;
}
AsyncTask是通过execute或executeOnExecutor启动的,通过上边对Executor的介绍可以知道,在executeOnExecutor()中的exec.execute(mFuture)这一行就是根据exec的实现方式来启动mFuture了,问题的关键是exec是如何实现execute()的。在execute中可以看到AsyncTask提供了一个默认的sDefaultExecutor,这个sDefaultExecutor是什么呢:
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
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);
}
}
}
默认情况下,sDefaultExecutor就是SerialExecutor类,通过源码可以看到,SerialExecutor是一个严格按照用户提交顺序来执行任务的执行者,其中scheduleNext()函数用来启动下一个任务:
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
THREAD_POOL_EXECUTOR就是真正启动任务的Executor:
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
ThreadPoolExecutor是java自己实现的一种Executor,顾名思义,是个提供线程池的Executor。
由上可以知道,当调用AsyncTask的execute()函数时,AsyncTask会按用户提交任务的顺序,在线程池里串行的执行任务(当前任务运行结束,再运行下一个)。
当然用户也可以提供自己的Executor来改变AsyncTask的运行方式。
Mikel