用于快速开启异步任务,处理耗时操作。在线程池中处理异步任务,同时可以将进度和处理结果提交到主线程处理。
Params 表示传入doInBackground参数的类型
Progress 表示后台任务执行进度的类型
Result 表示后台任务执行完成后返回结果的类型
若不需要传入具体的参数,传入Void即可
onPreExecute 执行任务之前,UI线程,在doInBackground执行之前
doInBackground 执行后台任务,子线程,can call publishProgress to publish updates on the UI thread
onProgressUpdate 进度更新,UI线程
onPostExecute 任务完成时,UI线程
onCancelled 任务取消时,并且onPostExecute不会执行,UI线程
InternalHandler AsyncTask内部Handler,处理任务的提交与更新的消息
SerialExecutor 串行线程池,用于任务调度,任务排队,一次只能执行一个任务
THREAD_POOL_EXECUTOR 线程池的实现者,用于真正执行任务
WorkerRunnable 实现了Callable接口,用于后台计算
1、 onPreExecute , 执行任务之前,运行在UI线程,在doInBackground执行之前
2、 Result = doInBackground() , 执行后台任务,返回执行结果,在线程池中执行,配合publishProgress来更新任务进度
3、 onProgressUpdate , 在doInBackground方法中调用publishProgress方法,用于进度更新,运行在UI线程(通过内部handler切换到主线程)
4、 onPostExecute , 运行在UI线程,处理运行结果(通过内部handler切换到主线程)
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
//实例化WorkerRunnable对象
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));
}
};
// 实例化FutureTask
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);
}
}
};
}
mWorker即WorkerRunnable对象,它是一个抽象类,并实现了Callable接口,用于计算一个任务
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
mFuture即FutureTask对象,下面用到了如下构造,
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
execute方法如下,它调用了executeOnExecutor方法,可以看到默认使用了sDefaultExecutor,即SerialExecutor
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
executeOnExecutor方法,此方法首先检查运行状态并赋以新状态,之后回调onPreExecute方法,并给mWorker赋以参数,最后让Executor执行任务,并返回AsyncTask对象。
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); // 传参FutureTask对象
return this;
}
exec即Executor对象,默认使用SerialExecutor(串行线程池),用于调度任务排队顺序执行。通过exec.execute(mFuture)开启任务调度,当有任务执行时,其他任务等待。mTasks即ArrayDeque,它是一个双端队列。第一次添加任务时,mTasks.offer将新任务添加到任务队列尾部,此时mActive这个Runnable为空,所以会直接走判断是否为空中的scheduleNext方法,并在此方法中通过THREAD_POOL_EXECUTOR.execute(mActive)开启执行任务。后续任务会走finally中的scheduleNext,此时mActive不为空。当执行r.run()方法,即调用了FutureTask对象的run方法
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);
}
}
FutureTask对象的run方法如下,callable对象即是在构造FutureTask对象时传入的mWorker,c.call()即在run方法中调用了mWorker的call方法,并将结果保存在result,call方法运行于子线程
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable; // callable对象即是在构造FutureTask对象时传入的mWorker
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
WorkerRunnable对象的call方法如下,它调用了doInBackground方法并将其返回值作为参数传给postResult方法。到此调用了doInBackground方法,它运行在线程池中
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
postResult方法,它会给AsyncTask内部的InternalHandler发送任务完成信息
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
InternalHandler如下,当消息类型为MESSAGE_POST_RESULT,通过finish方法完成执行结果的提交。当消息类型为MESSAGE_POST_PROGRESS时,回调更新进度onProgressUpdate方法。通过内部handler切换到主线程
private static class InternalHandler extends Handler {
@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;
}
}
}
finish方法如下,当任务没有取消时,调用onPostExecute,否则调用onCancelled。都运行在主线程
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
publishProgress,在doInBackground方法中调用,用以更新进度。此方法会向InternalHandler发送MESSAGE_POST_PROGRESS消息,以在UI线程更新进度
/**
* This method can be invoked from {@link #doInBackground} to
* publish updates on the UI thread while the background computation is
* still running. Each call to this method will trigger the execution of
* {@link #onProgressUpdate} on the UI thread.
*
* {@link #onProgressUpdate} will note be called if the task has been
* canceled.
*
* @param values The progress values to update the UI with.
*
* @see #onProgressUpdate
* @see #doInBackground
*/
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
案例简单模拟求和运算,并查看各个方法运行的线程
在MainActivity中自定义异步任务类继承AsyncTask
class BackTask extends AsyncTask<Integer, Integer, Integer> {
@Override
protected void onPreExecute() {
Log.e("TAG", "onPreExecute-任务执行之前,当前线程:"+Thread.currentThread().getName());
super.onPreExecute();
}
@Override
protected Integer doInBackground(Integer... params) {
Log.e("TAG", "doInBackground-任务执行中... ,当前线程:"+Thread.currentThread().getName());
int N = params[0];
int count = 0;
int total = 0; // 计算总和
Integer progress = 0; // 进度
while (count < N) {
++count;
total += count;
progress = count * 100 / N;
publishProgress(progress);
}
return total;
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
Log.e("TAG", "onPostExecute-执行结果,运算总和为" + result+" ,当前线程: "+Thread.currentThread().getName());
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.e("TAG", "onProgressUpdate-当前进度:" + values[0] + "%"+",当前线程:"+Thread.currentThread().getName());
}
}
在onCreate方法中开启任务
new BackTask().execute(100);
运行结果如下
09-07 08:33:53.508: E/TAG(2710): onPreExecute-任务执行之前,当前线程:main
09-07 08:33:53.508: E/TAG(2710): doInBackground-任务执行中... ,当前线程:AsyncTask #2
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:1%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:2%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:3%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:4%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:5%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:6%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:7%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:8%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:9%,当前线程:main
09-07 08:33:53.578: E/TAG(2710): onProgressUpdate-当前进度:10%,当前线程:main
... ... ... ... (省略部分输出)
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:90%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:91%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:92%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:93%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:94%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:95%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:96%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:97%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:98%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:99%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onProgressUpdate-当前进度:100%,当前线程:main
09-07 08:33:53.608: E/TAG(2710): onPostExecute-执行结果,运算总和为5050 ,当前线程: main