AnsyTask主要用来进行异步任务处理的,抽时间看了下AnsyTask的源码,记录一下过程。
类和成员变量的理解
先看了下他的类和属性,先对变量的意思有个大概的了解,可能有些出入。
一些类
-AsyncTaskResult
持有一个AsyncTask对象和一个数组,这个数组就是我们在onProgressUpdate或者onPostExecute中,在UI线程更新UI的回调数据
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
-InternalHandler
看到Hnadler肯定就猜想,在程序的运行过程中肯定有哪里会发送hanlder,去处理。这里,MESSAGE_POST_RESULT是一个任务结束了(可能是取消了,也可是执行完了);MESSAGE_POST_PROGRESS是任务还在持续进行
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;
}
}
}
-WorkerRunnable
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
是一个抽象类,且是Callable的子类。而他的初始化是在AsnyTask的构造方法中完成。
-FutureTask<>
FutureTask<> 是实现了RunnableFuture<>,而RunnableFuture<>则是继承了Runnable和Future。
FutureTask实现了Future的一些方法,如开启计算、取消计算、查询计算结果等,这里的计算,可以理解为我们的任务,计算开启或取消,对应任务的开启和取消等。但是查询计算结果只有在计算完成后才能通过get()方法获得,在计算没有完成前get()方法是阻塞的。当计算完成后,除非runAndReset(),否则不能重启或者取消计算。
这个对象的创建也是在AsnyTask的构造方法中完成。
-AtomicBoolean
理解为一种状态更新的标志,true或false,但是不能有boolean直接替换
-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);
}
}
}
SerialExecutor也是Executor的子类,重写了execute的方法,有序的执行队列里面的runnable
属性的理解
//大致意思是获取可用处理器的Java虚拟机的数量。
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//希望在核心线程池中最少有2个最多4个线程,通常比cpu数少一个更好,因为可以避免后台工作而引起CPU饱和
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
//最大线程池数,cpu数*2+1
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
//没有任务时线程活动的时间
private static final int KEEP_ALIVE_SECONDS = 30;
//一个线程工厂用于创建新的线程
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());
}
};
//一个阻塞队列,放置执行的runnable,队列长度为128
private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);
//一个可同时执行多个线程池的执行器
public static final Executor THREAD_POOL_EXECUTOR;
//静态代码块,创建线程池的执行者,并赋值给上面的THREAD_POOL_EXECUTOR
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,sPoolWorkQueue, sThreadFactory);
//设置为true,作用是让线程没有任务的时候也一直存在而不会停止
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
/*
* 这个执行器按顺序一次执行一个任务,而这个顺序对指定的进行是全局的
*/
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
//handler发送消息的两个标志
private static final int MESSAGE_POST_RESULT = 0x1;
private static final int MESSAGE_POST_PROGRESS = 0x2;
//默认的执行器
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
//一个handler
private static InternalHandler sHandler;
//一个比较核心的属性,是callable的子类
private final WorkerRunnable<Params, Result> mWorker;
//又是一个核心属性
private final FutureTask<Result> mFuture;
//一个标志task进行情况枚举状态,有还没有开始(PENDING)、正在进行(RUNNING)、结束(FINISHED)三个状态
private volatile Status mStatus = Status.PENDING;
//一个任务是否取消的状态标志
private final AtomicBoolean mCancelled = new AtomicBoolean();
//任务是否在运行的标志
private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
AsnyTask的构造方法
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
return postResult(result);
}
};
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 occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
构造方法中主要是做了两件事,分别初始化了WorkerRunnable的对象mWorker和FutureTask的对象mFuture。
- 初始化mWorker时,new了一个callable(),并实现了callable的call()方法,在call()方法中设置了任务的状态,调用了doInbackground(mParams)得到结果,最后调用postResult(result)。
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
//设置任务的是在运行状态
mTaskInvoked.set(true);
//运行在子线程
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//把传进来的参数传到doInBackground,对应我们的回调
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
return postResult(result);
}
};
在postResult(result)中,看到调用了handler发送异步消息,这就和前面的InternalHandler连接上了
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
在InternalHandler的handleMessage()中,对应MESSAGE_POST_RESULT的处理是:
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
而finish()中:
private void finish(Result result) {
if (isCancelled()) { //如果是取消的结束
onCancelled(result);
} else { //是task完成的结束,对应onPostExecute的回调
onPostExecute(result);
}
mStatus = Status.FINISHED; //最后把任务的状态置成FINISH
}
- 再来看mFuture的初始化
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 occurred while executing doInBackground()",e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
初始化时,把mWorker作为参数传进去,并重写了Future的done()方法,done()会执行postResultIfNotInvoked(get()),其中get()方法是获取的mWorker的call()的返回的结果
postResultIfNotInvoked(get()):
private void postResultIfNotInvoked(Result result) {
//获取任务的状态,但是在初始化mWorker时,该值已经被初始化为true,所以下面的if基本不会执行
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {
postResult(result);
}
}
最后来看AnsycTas的excute()方法
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
excute调用了executeOnExecutor(sDefaultExecutor, params),看属性赋值,sDefaultExecutor = SerialExecutor(),前面已经提过,SerialExecutor就是按照顺序去挨个执行里面的task
其中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;
exec.execute(mFuture);
return this;
}
在这个方法中,先判断当前的状态是否是Status.PENDING,然后把当前的状态置为Status.RUNNING,调用了onPreExecute(),对应了onPreExecute()的回调,可在主线程中做预处理。随即开始把 exec.execute(mFuture),及执行runnable。
exec即为sDefaultExecutor,就是我们前面说过的静态代码块里创建的线程池,这个线程池大小为cpu数量*2+1+阻塞线程数量128,虽然有一个数量大小的限制,但是SerialExecutor 里面的execute()可以看出,其实是一个任务一个任务执行的,及时并发量超过线程池大小,也不会出错。