我们通常在执行异步任务加载图片或者一些耗时任务的时候会用到AsyncTask这个类。今天看了AsyncTask的源码,做一个简单的分析
用法:
(1)定义自己的异步类
class MyAsyn extends AsyncTask{
@Override protected Object doInBackground(Object[] params) {
return null;
}
@Override protected void onPreExecute() {
super.onPreExecute();
}
@Override protected void onPostExecute(Object o) {
super.onPostExecute(o);
}
}
(2)调用
MyAsyn myAsyn = new MyAsyn();
myAsyn.execute();
源码分析
首先来看一下AsyncTask的构造方法
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);
}
}
};
}
代码比较长 其实主要就是对mFuture和mWorker进行了初始化,可以看到在初始化mWorker的时候 重写了call方法,里面正好有我们会调用的doInBackground
方法。而在初始化mFuture的时候则传入了mWorker作为参数,这个后面再讲,构造函数就这么多,接着我们来看一下execute()
方法
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
这个方法又调用了executeOnExecutor()方法,并且传入了一个sDefaultExecutor,这个参数一会儿再说。接着我们再来看一下executeOnExecutor()方法。的定义如下:
@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;
}
代码很短,我们看到了一个熟悉的函数 onPreExecute()方法,接着调用 exec.execute(mFuture);
方法,exec是什么呢,其实就是调用当前方法传进来的sDefaultExecutor,我们得找到这个变量的定义呀,接着看一下这个变量:
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new 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);
}
}
}
这个类比较简单,我们主要看execute方法和scheduleNext方法。execute方法中通过offer方法向mTasks添加callback其实就是往队列里面添加一系列的任务,添加一个之后,判断mActive的值是否为空,第一次为空,则调用scheduleNext方法,接着调用THREAD_POOL_EXECUTOR.execute(mActive);
我们来看一下THREAD_POOL_EXECUTOR这个静态变量:
/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
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;
}
这个静态变量的初始化是在静态代码块中进行的,当调用THREAD_POOL_EXECUTOR.execute(mActive);
方法时,便新开了一个线程进行任务处理,调用mFuture的run方法:
public void run() {
if (state != NEW ||
!U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
可以看到在mFuture的run方法中有一个callable,实际上这个callable就是mFuture在初始化时传入的mWorker,该方法最终调用worker的call方法,进而调用doInBackground方法。