AsyncTask 源码详解
2017-10-13 本文已影响0人
刘佳阔

1.常规写法
//三个参数的意思分别是,线程执行的参数类型,线程异步执行进度的任务类型,返回值的类型
private class MyAsync extends AsyncTask<Params, Progress, Result> {
@Override
protected Result doInBackground(Params... params) { //此方法在子线程执行,参数就是上文的Params类型
publishProgress(6); //这个方法可以把异步执行进度发布到主线程去,参数是 Progress类型
return 6L;
}
@Override
protected void onPostExecute(Result aLong) {//在异步线程完成后被调用,运行在主线程
super.onPostExecute(aLong);
}
@Override
protected void onCancelled() {//异步任务被取消时调用,他和onPostExecute 只能有一个被调用
super.onCancelled();
}
@Override
protected void onPreExecute() {//该方法在异步任务执行前调用,运行在主线程
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Progress... values) { //publishProgress调用后,就把参数传到了这个方法里,运行在主线程,用来更新异步任务执行进度
super.onProgressUpdate(values);
}
}
然后在主线程中调用
new MyAsync().execute("a"); //这句话必须在主线程中调用.对象的创建和execute的执行,都必须在主线程
2 源码讲解
1.先从成员变量看起
public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); //一个继承自Executor的内部类, 注意是用来把线程添加进线程的任务集合
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
private static InternalHandler sHandler;//内部用来发送消息给主线程的Handler
private final WorkerRunnable<Params, Result> mWorker; //内部类,继承自Callable,用来返回线程的结果与Runnable 类似.只是Runnable 不能返回结果.
private final FutureTask<Result> mFuture; // FutureTask的子类,也是Runnable的子类,可以取消线程及获得线程的执行结果.
2.构造函数
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() { //标识接受的参数类型和返回的参数类型
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//设置优先级
result = doInBackground(mParams);
//可以看到.在mWorker的call方法被调用时,会执行暴露的doInBackground()方法,意味着call要在子线程
执行,同事把结果保存在result中.这才是真正工作的地方.
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result); //发送结果的方法.下边讲解
}
return result;
}
};
//mFuture对象封装了mWorker的call方法,当mFuture对象被提交到AsyncTask包含的线程池执行时,call方法就会被调用
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());//没有执行的话,也发送一个消息出去
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
-
execute 方法
@MainThread //标识了需要在主线程调用 public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); //sDefaultExecutor 是 SerialExecutor类的对象 } @MainThread public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { mStatus = Status.RUNNING; //更新状态 onPreExecute(); //这是在异步线程执行前调用的方法,在主线程中, mWorker.mParams = params; //params 是我们输入的参数,mWorker会在call方法被调用是把参数传到doInBackground 方法中,间构造函数. exec.execute(mFuture);//exec 是sDefaultExecutor return this; }
- sDefaultExecutor.exec
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();//以数组的形式储存所有要执行的后台任务
Runnable mActive; //当前正执行的异步线程
public synchronized void execute(final Runnable r) {//此时的 r是上文的 mFuture
mTasks.offer(new Runnable() {//mTasks会把 runnable添加到数组的最后边,
public void run() {
try {
r.run(); //可以看到,在执行万mRuture的方法后,还要同mTasks中取出下一任务,穿行执行
} finally {
scheduleNext();
}
}
});
if (mActive == null) {//第一次尽量.肯定为null,然后就从mTasks中取出任务执行
scheduleNext();
}
}
//从上边的方法可以看到.sDefaultExecutor 的作用仅仅是把线程添加到数组中,同时使线程可以穿行执行.
//而下边的方法可看出.真正执行线程运行的,是 THREAD_POOL_EXECUTOR 这个Executor
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
- THREAD_POOL_EXECUTOR
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); //cpu核心数
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));//核心线程数2-4
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; //最大线程数
private static final int KEEP_ALIVE_SECONDS = 30; //线程存活时间.
public static final Executor THREAD_POOL_EXECUTOR;
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
6.Handler.
在 5中执行了mFuture 的run方法后, 会调用 没Worker的call方法,在doInBackground之后,调用了
postResult(result);方法.
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
//getHandler 返回的是 sHandler 是一个Handler的实现类.
message.sendToTarget();
return result;
}
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]); //此时的result.mTask 就是我们new的 AsyneTask,这里是线程完成后的消息处理,下边是 调用 publishProgress 的消息处理.
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;
}
这里.就分析完成,最后大概记录一下.AsyncTask开始执行时,会把参数封装进 (WorkerRunnable) mWorker,然后mWorker 是被(FutureTask) mFuture所持有.执行时, (SerialExecutor) sDefaultExecutor把
(FutureTask) mFuture 进行封装后添加进线程集合(ArrayDeque<Runnable>) mTask并调用 (ThreadPoolExecutor) THREAD_POOL_EXECUTOR 的execute方法, 从 (ArrayDeque<Runnable>) mTask 开始执行线程,然后 (FutureTask) mFuture 被执行时,会调用 (WorkerRunnable) mWorker 的call方法,call方法又会调用AsyncTask 的 doInBackground()方法,真正在子线程开始执行, doInBackground的返回结果会通过内部的(InternalHandler) sHandler 发送并处理, (InternalHandler) sHandler 处理时会调用AsyncTask的finish 方法,finish方法要么执行onCancelled,要么执行onPostExecute.到此.异步执行完成