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;
- }
- }
- }
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以后的源码。