1、AsyncTask的构造方法
AsyncTask中最重要的四个方法:onPreExecute,doInBackground,onProgressUpdate,onPostExecute那么这四个方法是如何执行的,又是如何传递参数的呢?想知道AsyncTask类的内部工作方式,我们就必须了解AsyncTask的构造方法。
1)初始化WorkerRunnable对象mWorker,并实现了call()方法。
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return doInBackground(mParams);
}
};
而WorkerRunnable类实现了Callable接口,并且有一个Params[] mParams成员变量
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
2)初始化FutureTask对象mFuture,并实现了done()方法。这里实现的方式有些复杂,接下来会逐一解释
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
Message message;
Result result = null;
try {
result = 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) {
message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
message.sendToTarget();
return;
} catch (Throwable t) {
throw new RuntimeException("An error occured while executing "
+ "doInBackground()", t);
}
message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
};
第一、我们需要关心FutureTask类
我们注意到FutureTask类实现了RunnableFuture接口
public class FutureTask<V> implements RunnableFuture<V>
而实际上RunnableFuture接口只是分别继承了Runnable和Future接口,其中的run()方法就是Runnable中的run()方法。
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
第二、了解了Future类,接下来我们需要看看它的构造方法,看到这里我们发现实际上是用mWorker初始化FutureTask类的sync常量。
public class FutureTask<V> implements RunnableFuture<V> {
private final Sync sync;
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new Sync(callable);
}
第三、需要了解Sync的构造方法,将mWorker传递给了Sync类的callable常量。
private final Callable<V> callable;
Sync(Callable<V> callable) {
this.callable = callable;
}
至此,构造方法部分已经介绍完了,那么接下来我们就来看看AsyncTask类是怎么工作的
2、AsyncTask的execute方法
1)执行onPreExecute()
这里我们就不用过多解释了,很明显第一步就执行了onPreExecute()方法。
public final AsyncTask<Params, Progress, Result> execute(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;
sExecutor.execute(mFuture);
return this;
}
但我们需要注意的是,将传入的params参数赋值给了mWorker中的mParams,这一步实现了参数的传递。并且调用了sExecutor.execute(mFuture),而sExecutor就是ThreadPollExecutor,execute自然会执行mFuture的run方法了。
private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
2)执行doInBackground(Params... params)
执行mFuture的run方法后,我们很容易就看到了首先执行的就是callable.call()
public void run() {
sync.innerRun();
}
void innerRun() {
if (!compareAndSetState(READY, RUNNING))
return;
runner = Thread.currentThread();
if (getState() == RUNNING) { // recheck after setting thread
V result;
try {
result = callable.call();
} catch (Throwable ex) {
setException(ex);
return;
}
set(result);
} else {
releaseShared(0); // cancel
}
}
在前面Sync的构造方法中,我们已经将mWorker赋值给了callable,所以自然会执行mWorker的call()方法了,这里重复贴下代码:
public Result call() throws Exception {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return doInBackground(mParams);
}
从而实现了将execute(Params ... params)中的形参params传递给了mWorker,再传递给doInBackground方法,同时执行了该方法。
3)执行onPostExecute(Result result)
首先我们重贴下代码:
void innerRun() {
if (!compareAndSetState(READY, RUNNING))
return;
runner = Thread.currentThread();
if (getState() == RUNNING) { // recheck after setting thread
V result;
try {
result = callable.call();
} catch (Throwable ex) {
setException(ex);
return;
}
set(result);
} else {
releaseShared(0); // cancel
}
}
其中得到了call()方法的返回结果result = callable.call() //实际上就是doInBackground的返回结果。
接着set(result),就是传递result的过程。实际上就是将得到的执行后的返回结果result赋值给了Sync类中的result对象,后面会通过Sync类中的get()方法再次得到该对象。
protected void set(V v) {
sync.innerSet(v);
}
void innerSet(V v) {
for (;;) {
int s = getState();
if (s == RAN)
return;
if (s == CANCELLED) {
// aggressively release to set runner to null,
// in case we are racing with a cancel request
// that will try to interrupt runner
releaseShared(0);
return;
}
if (compareAndSetState(s, RAN)) {
result = v;
releaseShared(0);
done();
return;
}
}
}
最后,执行了FutureTask的done()方法。如下重贴代码:
protected void done() {
Message message;
Result result = null;
try {
result = 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) {
message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
message.sendToTarget();
return;
} catch (Throwable t) {
throw new RuntimeException("An error occured while executing "
+ "doInBackground()", t);
}
message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
这里的Result result = get()实现了doInBackground返回值的传递。
public V get() throws InterruptedException, ExecutionException {
return sync.innerGet();
}
V innerGet() throws InterruptedException, ExecutionException {
acquireSharedInterruptibly(0);
if (getState() == CANCELLED)
throw new CancellationException();
if (exception != null)
throw new ExecutionException(exception);
return result;
}
接下来在done()方法中调用了
message = sHandler.obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
AsyncTaskResult就用来保存返回结果,并且通过发送消息的方式传递给对应的handler处理。
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
从而实现了将result传递给onPostExecute(Result... result)的目的,同时调用了该方法
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;
case MESSAGE_POST_CANCEL:
result.mTask.onCancelled();
break;
}
}
}
最后,我们似乎忘记了onProgressUpdate(Progress... values)方法,不过没关系我本来就是要放在最后才讲的。
4)执行onProgressUpdate(Progress... values)
这个方法顾名思义就是为了在任务执行过程中更新状态信息,并且和其他几个方法不同的是由我们来决定是否更新,以及什么时候更新。通常我们会在doInBackground方法中显示的调用publishProgress来更新状态。
protected final void publishProgress(Progress... values) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
这样,通过发送消息的方式也交由对应的handler来处理,过程见3)中handleMessage方法。
至此我们就对AsyncTask类的实现方式有了一定的了解了。