AsyncTask优缺点
一、优点:AsyncTask是一种轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行进度和最终结果传递给主线程并在主线程中更新UI。通过AsyncTask可以更方便的执行后台任务及更新UI;
AsyncTask提供了四个核心方法,使得使用起来很方便:
1、onPreExecute(),工作在主线程,任务开始前的准备工作
2、doInBackground(Params...params),在线程池执行,params表 示异步任务输入的参数;此方法中会调用publishProgress()来更新任务进度,publishProgress()会调用onProgressUodate方法。 doInBackground执行完毕后返回计算结果。
3、onProgressUodate(Progress...values),主线程运行,后台任务进度发生改变时调用。
4、onPostExecute(Result result),在主线程执行,result为doInBackground返回值
二、缺点:
1.线程池容量不够抛出异常
CORE_POOL_SIZE 核心线程数
MAXIMUM_POOL_SIZE 最大线程数量
KEEP_ALIVE 1s闲置回收
TimeUnit.SECONDS 时间单位
sPoolWorkQueue 异步任务队列
sThreadFactory 线程工厂
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
如果当前线程池中的数量小于corePoolSize,创建并添加的任务。
如果当前线程池中的数量等于corePoolSize,缓冲队列 workQueue未满,那么任务被放入缓冲队列、等待任务调度执行。
如果当前线程池中的数量大于corePoolSize,缓冲队列workQueue已满,并且线程池中的数量小于maximumPoolSize,新提交任务会创建新线程执行任务。
如果当前线程池中的数量大于corePoolSize,缓冲队列workQueue已满,并且线程池中的数量等于maximumPoolSize,新提交任务由Handler处理。
当线程池中的线程大于corePoolSize时,多余线程空闲时间超过keepAliveTime时,会关闭这部分线程。
2.内存泄露(所以最好任务执行时间少一点)
AsyncTask提供的cancell方法只是一个修改标志的方法,并没有真正的停止任务的执行,当人无论寻到此标志时才会停止。
持有外部引用,外部销毁后任务在运行,内存不会回收
3.一个线程,一个异步任务
三、源码分析
AsyncTask中有两个线程池:sDefaultExecutor和THREAD_POOL_EXECUTOR,和一个Handler:InternalHandler.其中sDefaultExecutor负责任务的排队,THREAD_POOL_EXECUTOR负责真正的执行,InternalHandler用于线程池到主线程的通信,将执行环境从线程池转移到主线程。
首先从默认的执行入口看:
private final WorkerRunnable<Params, Result> mWorker;
private final FutureTask<Result> mFuture;
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
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;
}
sDefaultExecutor是一个串行的线程池,所有的任务都在此线程池中排队执行,所以多个任务的执行默认是串行的,从任务队列拿到任务就从线程池中拿到一个线程去执行,执行完成循环下一个任务并从线程池拿线程直到任务完成或者取消:
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
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);
}
}
}
从上面可以看出,执行的具体是mFuture(FutureTask),FutureTask是一个并发类,实现了RunnableFuture接口(RunnableFuture继承了Runable和Future借口)。SerialExecutor 的execute会把FutureTask插入mTasks,并且如果没有正在执行的(mActive)就scheduleNext(),执行下一个任务。
在AsyncTask构造函数中,FutureTask和WorkerRunable(是一个Callable,执行带返回值,所以可以得到返回结果)初始化
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
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 occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
线程池执行Futuretask(run),FutureTask的run方法会调用WorkerRunnable的call方法,在call中调用了doInBackground方法并将执行结果返回给postResult方法。
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
其中拿到的Handler就是InternalHandler,在handelMessage中处理
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
Hanlder的处理就将返回结果拿到了主线程中,中兴主线程的onProgressUpdate和finish(onPostExecute)方法