在封装Retrofit下载文件时:
final SaveFileTask task = new SaveFileTask(REQUEST, SUCCESS);
//继承AsyncTask
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, DOWNLOAD_DIR, EXTENSION, responseBody, NAME);
为什么这个我们不是调用excute()方法?往下看
AsyncTask的execute()函数
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
调用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;
}
- exec是什么?是调用exceute()时传入的sDefaultExecutor
- sDefaultExecutor是什么? 是它的一个实例。 new SerialExecutor();
- sDefaultExecutor是SerialExecutor的一个实例,而且它是个静态变量。也就是说,一个进程里面所有AsyncTask对象都共享同一个SerialExecutor对象。
那么所有的秘密就在于SerialExecutor的execute函数了。
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是一个一个执行任务的,而所有的对象共享一个 SerialExecutor对象(静态成员),所以多个AsyncTask是串行的。demo:
final AsyncTask task = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
Log.e("tag", "task 1 " + " start");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("tag", "task 1 " + " end");
return null;
}
};
task.execute();
// task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
final AsyncTask task2 = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
Log.e("tag", "task 2 " + " start");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("tag", "task 2 " + " end");
return null;
}
};
task2.execute();
// task2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
1.png
如何并行执行多个AsyncTask对象
使用THREAD_POOL_EXECUTOR
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
线程池中核心线程数、最大线程数。。。。。怎么调度的再议,但是有一点可以肯定,它不是排队在一个线程里面执行的
final AsyncTask task = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
Log.e("tag", "task 1 " + " start");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("tag", "task 1 " + " end");
return null;
}
};
// task.execute();
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
final AsyncTask task2 = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
Log.e("tag", "task 2 " + " start");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.e("tag", "task 2 " + " end");
return null;
}
};
// task2.execute();
task2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
2.png
网友评论