在Android - Handler 、AsyncTask(一)一文中,我们提到,为了解决不能阻塞主线程和不能在子线程中更新UI的问题,android提供了handler消息机制。
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); //从AsyncTask.java中可知,sDefaultExecutor为AsyncTask的内部类SerialExecutor的实例: /*public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;*/ }executeOnExecutor()方法的具体逻辑如下:
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { //PENDING的API注释为:Indicates that the task has not been executed yet. 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)"); } } //Status是AsyncTask的一个内部枚举类,用来标示任务的状态,从上边的代码中可以看到,如果 //mStatus 的值为RUNNING或者FINISHED,则会抛出异常,并且在execute()方法一执行时 //就将mStatus 的值设为了RUNNING,即一个任务只能执行一次 mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }关于上边第19行的onPreExecute()方法,在AsyncTask类中的定义及注释如下:
/** * Runs on the UI thread before {@link #doInBackground}. */ protected void onPreExecute() { //该方法在UI线程中被执行,可以做一些初始化的工作,AsyncTask的子类可以选择性的复写该方法 }
我们创建myAsyncTask类的实例时,在AsyncTask的构造函数中就已经完成了对mWorker和mFuture两个对象的初始化,mWorker是AsyncTask内部实现了Callable接口的一个类WorkerRunnable的实例:
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }
private static class SerialExecutor implements Executor { //需要注意的是,Executor为线程池体系的顶级接口,内部只定义了一个空方法: /*public interface Executor { *//** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thread, or in the calling * thread, at the discretion of the {@code Executor} implementation. *//* void execute(Runnable command); }*/ //即SerialExecutor 并不是线程池,它只是复写了execute()方法,可认为它就是一个可执行任务的执行器 //定义一个ArrayDeque成员变量,ArrayDeque没有容量限制,是线程不安全的(此处不详解) final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); //定义一个Runnable类型的临时变量mActive Runnable mActive; //注意该方法使用了synchronized 关键字进行修饰 public synchronized void execute(final Runnable r) { //在mTasks队列的尾部插入一个Runnable r mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { //poll()方法从队列的头部检索并删除一个对象,并将检索到的对象返回 if ((mActive = mTasks.poll()) != null) { //如果poll()方法返回的mActive不为null的话, //将会调用THREAD_POOL_EXECUTOR.execute(mActive); 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); //THREAD_POOL_EXECUTOR是AsyncTask类的成员变量,被static和final修饰,是一个线程池对象, //它的各个参数的值分别如下(关于这些值,这里不做解释): private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE = 1; private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } }; private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);
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); } } }; }
/** * A cancellable asynchronous computation. This class provides a base implementation of {@link Future}, * with methods to start and cancel a computation, query to see if the computation is complete, and * retrieve the result of the computation. The result can only be retrieved when the computation has * completed; the {@code get} methods will block if the computation has not yet completed. Once * the computation has completed, the computation cannot be restarted * or cancelled (unless the computation is invoked using {@link #runAndReset}). * <p>A {@code FutureTask} can be used to wrap a {@link Callable} or * {@link Runnable} object. Because {@code FutureTask} implements * {@code Runnable}, a {@code FutureTask} can be submitted to an * {@link Executor} for execution. */ //一个可取消的异步计算,该类提供了基于Future的一些方法实现,通过这些方法可以开启或退出一个计算,可以 //查看一个计算是否完成并检索计算的结果,如果计算尚未完成,用于检索结果的get方法将会被阻塞,一旦计算 //完成,除非调用runAndReset,否则计算不会被重新启动或者取消,一个FutureTask可以用来包装一个 //Callable或者Runnable对象,因为FutureTask implements Runnable, //一个FutureTask可以被提交给Executor进行执行(只是大致翻译,对这个类有个大概了解) public class FutureTask<V> implements RunnableFuture<V> { //public interface RunnableFuture<V> extends Runnable, Future<V>{} }可以看出,FutureTask类的存在是为了对一个任务进行包装,为的是能够更好地控制这个任务。
public FutureTask(Runnable runnable, V result) { this.callable = Executors.callable(runnable, result); this.state = NEW; // ensure visibility of callable }Executors类中的callable(runnable, result)方法:
public static <T> Callable<T> callable(Runnable task, T result) { if (task == null) throw new NullPointerException(); return new RunnableAdapter<T>(task, result); }Executors类中的内部类RunnableAdapter:
/** * A callable that runs given task and returns given result */ static final class RunnableAdapter<T> implements Callable<T> { final Runnable task; final T result; RunnableAdapter(Runnable task, T result) { this.task = task; this.result = result; } public T call() { task.run(); return result; } }可以看到,这个构造函数将接收的Runnable task和T result作为参数构造出一个Callable的间接子类对象,并且该对象的call方法中执行的就是task的run方法。然后将这个对象赋给了FutureTask的成员变量callable。
public FutureTask(Callable<V> callable) {//同样注意泛型 if (callable == null) throw new NullPointerException(); //将接收的callable赋给FutureTask的成员变量private Callable<V> callable; this.callable = callable; this.state = NEW; // ensure visibility of callable }和第一个构造函数一样,重点也是在 为FutureTask的成员变量callable赋值
public void run() { if (state != NEW ||!UNSAFE.compareAndSwapObject(this, runnerOffset,null, Thread.currentThread())) return; try { Callable<V> c = callable;//将callable赋值给临时定义的allable<V>变量c if (c != null && state == NEW) { V result;//定义临时变量V result(泛型) boolean ran;//定义临时boolean变量ran try { //执行c的call()方法,这一步是关键 result = c.call(); //将ran的值设置为true 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); } }
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)); } };终于看到了我们的doInBackground()方法了,顺便看一下这个方法 在AsyncTask.java中的定义吧:
/** * Override this method to perform a computation on a background thread. The * specified parameters are the parameters passed to {@link #execute} * by the caller of this task. * This method can call {@link #publishProgress} to publish updates * on the UI thread. * @param params The parameters of the task. * @return A result, defined by the subclass of this task. */ //可以看到,该方法是个空方法,注释也通俗易懂,不翻译了 protected abstract Result doInBackground(Params... params);看到这里,也就明白了AsyncTask是怎样把我们定义到doInBackground()方法中的任务放到后台去执行的了。doInBackground()方法执行完之后,其返回值将作为postResult()方法的参数,来看postResult()方法:
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
private static class AsyncTaskResult<Data> {//同样需要注意泛型 final AsyncTask mTask; final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } }代码比较简单,需要发送的消息的obj值就是一个AsyncTaskResult对象,其成员变量final AsyncTask mTask的值为this,成员变量final Data[] mData的值则是doInBackground()方法的返回值。消息创建好,并且发送出去了,我们来看一下消息的处理:
private static class InternalHandler extends Handler { @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { //先取得AsyncTaskResult 类型的消息的obj--result AsyncTaskResult result = (AsyncTaskResult) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: //接收到上文中的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; } } }消息处理方式为 result.mTask(即该AsyncTask对象)的finish方法(),参数为result.mData[0](即doInBackground()方法的返回值),来看finish方法()的具体逻辑:
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { //如果任务没有退出,则执行onPostExecute(result)方法 onPostExecute(result); } mStatus = Status.FINISHED; }再来看onPostExecute(result)方法的定义:
/** * <p>Runs on the UI thread after {@link #doInBackground}. The * specified result is the value returned by {@link #doInBackground}.</p> * <p>This method won't be invoked if the task was cancelled.</p> * @param result The result of the operation computed by {@link #doInBackground}. */ //注释同样比较简单,不做翻译了 @SuppressWarnings({"UnusedDeclaration"}) protected void onPostExecute(Result result) { }
/** * 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. */ //后台计算正在进行时可以在doInBackground()方法中调用此方法 //每一次调用这个方法都会导致onProgressUpdate()方法在UI线程中被执行 //接收的参数类型为AsyncTask<Params, Progress, Result>接收的泛型类型Progress protected final void publishProgress(Progress... values) { if (!isCancelled()) { sHandler.obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } }publishProgress()方法和我们上边讲到过的postResult()方法一样,主要逻辑都是创建一条消息并且发送出去。只是在这里,消息的what值是MESSAGE_POST_PROGRESS,消息的obj值为new AsyncTaskResult<Progress>(this, values),消息的处理:
public void handleMessage(Message msg) { //先取得AsyncTaskResult 类型的消息的obj--result AsyncTaskResult result = (AsyncTaskResult) msg.obj; switch (msg.what) { ... ... //接收到上文中的MESSAGE_POST_PROGRESS消息后的处理逻辑为: case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } }和wha t值为MESSAGE_POST_RESULT的消息的处理类似,直接看 onProgressUpdate() 方法的定义:
/** * Runs on the UI thread after {@link #publishProgress} is invoked. * The specified values are the values passed to {@link #publishProgress}. * @param values The values indicating progress. */ //在publishProgress()方法被调用之后,在UI线程中执行 @SuppressWarnings({"UnusedDeclaration"}) protected void onProgressUpdate(Progress... values) {//空方法}