* @see #onPreExecute
* @see #onPostExecute
* @see #publishProgress
* @see #doInBackground
其中最重要的就是doInBackground(),所有的异步操作都在doInBackground里实现,注意,ui更新等操作千万别在此方法内。
下面从源代码入手,深入谈下正确使用该类的姿势。
AsyncTask默认维护了一个线程池。
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
SERIAL_EXECUTOR 即 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);
}
}
}
再看 THREAD_POOL_EXECUTOR;
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;
默认最小的线程数时5,最大的线程数时128,线程的空闲时间为1秒。
从api11 以后,为了防止发生应用层错误,只允许同时有一条线程在执行,而且默认是由SerialExecutor按顺序执行的
另外,在页面activity,fragment dialog退出的时候,如果当中调用了AsyncTask,记得cancel.否则,如果在onPostExecute中调用了
ui操作,会导致异常发生。
例子如下:当执行网络操作的时候,当服务器返回结果的时候,dialog的页面不存在,会报错。