在封裝Retrofit下載文件時:
final SaveFileTask task = new SaveFileTask(REQUEST, SUCCESS);
//繼承AsyncTask
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, DOWNLOAD_DIR, EXTENSION, responseBody, NAME);
為什么這個我們不是調(diào)用excute()方法?往下看
AsyncTask的execute()函數(shù)
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
調(diào)用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是什么?是調(diào)用exceute()時傳入的sDefaultExecutor
- sDefaultExecutor是什么? 是它的一個實例。 new SerialExecutor();
- sDefaultExecutor是SerialExecutor的一個實例,而且它是個靜態(tài)變量。也就是說,一個進程里面所有AsyncTask對象都共享同一個SerialExecutor對象。
那么所有的秘密就在于SerialExecutor的execute函數(shù)了。
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是一個一個執(zhí)行任務(wù)的,而所有的對象共享一個 SerialExecutor對象(靜態(tài)成員),所以多個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
如何并行執(zhí)行多個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);
線程池中核心線程數(shù)、最大線程數(shù)。。。。。怎么調(diào)度的再議,但是有一點可以肯定,它不是排隊在一個線程里面執(zhí)行的
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