在封裝Retrofit下載文件時(shí):
final SaveFileTask task = new SaveFileTask(REQUEST, SUCCESS);
//繼承AsyncTask
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, DOWNLOAD_DIR, EXTENSION, responseBody, NAME);
為什么這個(gè)我們不是調(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);//這一行是重點(diǎn)
return this;
}
- exec是什么?是調(diào)用exceute()時(shí)傳入的sDefaultExecutor
- sDefaultExecutor是什么架忌? 是它的一個(gè)實(shí)例缀去。 new SerialExecutor();
- sDefaultExecutor是SerialExecutor的一個(gè)實(shí)例羡滑,而且它是個(gè)靜態(tài)變量谴忧。也就是說哎垦,一個(gè)進(jìn)程里面所有AsyncTask對象都共享同一個(gè)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是一個(gè)一個(gè)執(zhí)行任務(wù)的,而所有的對象共享一個(gè) SerialExecutor對象(靜態(tài)成員)荚坞,所以多個(gè)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í)行多個(gè)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)度的再議临谱,但是有一點(diǎn)可以肯定,它不是排隊(duì)在一個(gè)線程里面執(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