AsyncTask实现原理和内部代码

Android从1.5开始引入了AsyncTask这个类,可以帮助我们解决线程和界面刷新问题,主要是对Thread+Handler这样的封装,但在设计模式和代码维护方面都有不错的表现。对于AsyncTask的实现原理和内部的代码如何实现Android123一起和大家分享,早在2008年时Google推出了一个示例应用叫PhotoStream来演示UI在多线程网络慢速I/O下的刷新问题,里面的线程构造使用的正是AsyncTask的雏形,由于内部使用Java 1.5的并发库比普通初级Android开发者编写的Thread+Handler稳定很多,下面我们就android.os.AsyncTask的实现

public abstract class AsyncTask<Params, Progress, Result> {
private static final String LOG_TAG = “AsyncTask”;

private static final int CORE_POOL_SIZE = 5; //线程池数量
private static final int MAXIMUM_POOL_SIZE = 128; //线程池中最大线程数
private static final int KEEP_ALIVE = 1;

private static final BlockingQueue<Runnable> sWorkQueue =
        new LinkedBlockingQueue<Runnable>(10); //使用并发库的阻塞队列初始时保存10个Runnable对象

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 ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
        MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); //创建线程池

private static final int MESSAGE_POST_RESULT = 0x1; 
private static final int MESSAGE_POST_PROGRESS = 0x2;
private static final int MESSAGE_POST_CANCEL = 0x3;

private static final InternalHandler sHandler = new InternalHandler(); //这个是对Handler的封装,内部处理Thread的状态。

private final WorkerRunnable<Params, Result> mWorker;  //该类对Runnable做简单封装
private final FutureTask<Result> mFuture; //对于并发库而言FutureTask是最重要的,有兴趣的网友可以看下JDK源码

private volatile Status mStatus = Status.PENDING; //保存当前线程状态

public enum Status { //枚举类记录当前线程状态
    PENDING,
    RUNNING,
    FINISHED,
}

public AsyncTask() {
    mWorker = new WorkerRunnable<Params, Result>() { //构造Runable对象
        public Result call() throws Exception {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //设置线程优先级为后台,这里Android开发网提示大家低于标准线程优先级
            return doInBackground(mParams);
        }
    };

    mFuture = new FutureTask<Result>(mWorker) { 
        @Override
        protected void done() {
            Message message;
            Result result = null;

            try {
                result = get();
            } catch (InterruptedException e) { //处理Thread中断异常
                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)); //执行完后通过Handler通知结果
            message.sendToTarget();
        }
    };
}

public final Status getStatus() {
    return mStatus;
}

protected abstract Result doInBackground(Params... params);

protected void onPreExecute() {
}

protected void onPostExecute(Result result) {
}

protected void onProgressUpdate(Progress... values) {
}

protected void onCancelled() {
}

public final boolean isCancelled() {
    return mFuture.isCancelled();
}

public final boolean cancel(boolean mayInterruptIfRunning) {
    return mFuture.cancel(mayInterruptIfRunning);
}

public final Result get() throws InterruptedException, ExecutionException {
    return mFuture.get();
}

public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
        ExecutionException, TimeoutException {
    return mFuture.get(timeout, unit);
}

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;
}

protected final void publishProgress(Progress... values) { //通过Handler通知UI刷新
    sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
            new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}

private void finish(Result result) {
    if (isCancelled()) result = null;
    onPostExecute(result);
    mStatus = Status.FINISHED;
}

private static class InternalHandler extends Handler { //和我们的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;
        }
    }
}

private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
    Params[] mParams;
}

@SuppressWarnings({"RawUseOfParameterizedType"})
private static class AsyncTaskResult<Data> {
    final AsyncTask mTask;
    final Data[] mData;

    AsyncTaskResult(AsyncTask task, Data... data) {
        mTask = task;
        mData = data;
    }
}

}

经过上面的简单分析相信大家对Android AsyncTask会有更加深刻的理解,整个AsyncTask实现基于Thread+Handler,但对于Thread使用的是Java的并发包的FutureTask具体的可以参考JDK5以后的源码。