AsyncTask 是android原生提供的异步任务,其内部有
onPreExcute() 任务执行前调用,完成请求前的初始化工作;
doInBackGround() 任务执行,放在只线程中执行,如果期间进度发生改变会调用onProgressUpdate(),并在任务执行完成调用onPostExcute();
onPostExcute(),任务执行完成调用
注:AsyncTask方法必须在main线程中声明并调用,并且只能初始化一次,也只能调一次excute(),具体
new AsyncTask().excute(Void, Void, Void);
上诉几个回调方法不能主动调用,由于AsyncTask内部维护了一个线程池,在1.6之前串行处理任务,1.6改成并行执行任务,后来并发有问题在3.0改成串行执行任务,但是可以通过
new AsyncTask().excuteOnExcutor(Void, Void, Void);并行执行任务
下面通过源码来分析AsyncTask();
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);
}
}
}
SerialExcutor线程池用来线程队列排队,从代码可以看出是串行执行,
还有另外一个线程池THREAD_POOL_EXECUTOR,任务执行的线程池
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;
}
}
}
InternalHandler静态的用于消息发送到ui线程,这也是为什么要在main线程初始化的原因
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
return postResult(result);
}
};
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 occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
FutureTask用来将传入的Params转化成FutureTask