使用AsyncTask原因:
1.能够后台执行耗时任务2.能够在回调接口中直接更新UI
那么问题来了,它是如何做到的呢? Handler+Thread ?
没错,AsyncTask底层就是 采用Thread+Handler的方式实现的。
我们根据源码分别进行分析:
1.Handler:
private static final InternalHandler sHandler = new InternalHandler();
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;
}
}
}
AsyncTask 内部声明了静态内部类InternalHandler,并实例化了一个静态的Handler实例,这就要求AsyncTask在进行实例化必须在UI线程中进行,这样InternalHandler 就可以复用UI线程中的MainLooper,我们知道MainLooper运行在主线程中。
2.线程池
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
a.默认情况下,AsyncTask通过SerialExecutor对线程进行管理(线性执行),所以在AsyncTask中不应当执行耗时较长的任务。
b.通过调用executeOnExecutor()方法可以实现任务的并发执行。用户可以传递自定义的Executor(如:FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)。
c.注意:executorOnExecutor()方法中调用了onPreExecute()方法,而onPreExecutor()方法中可以直接操作UI,这就要求用户必须在UI线程中调用execute等方法。
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;
}