在深入码字之后越发觉得源码那么重要,于是开始了源码阅读之旅,下面来走进Android源码的世界。
AsyncTask源码分析---------------------------------------------------------------------------------------
AsyncTask基本使用
AsyncTask asyncTask = new AsyncTask<Void, Void, Void>() { @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); } @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPreExecute() { super.onPreExecute(); } }; asyncTask.execute();
证明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); return this; }
最后调用了exec.execute(mFuture),里面传递了一个mFuture对象,根据这个继续看源码
public class FutureTask<V> implements RunnableFuture<V> {
这个也是实现了一个RunnableFuture,然而这个也是继承于Runnable的
public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run(); }
这个时候我们去看FutureTask的run方法
public void run() { if (state != NEW || !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread())) return; try { Callable<V> c = callable; 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); }
因为这里有一个callable对象,此刻的callable对象就是最开始的AsyncTask传过来的mWork对象,在run方法里调用了c.call();所以这个时候我们去查看AsyncTask下的mWord的call()方法
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Result result = null; try { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked result = doInBackground(mParams); Binder.flushPendingCommands(); } catch (Throwable tr) { mCancelled.set(true); throw tr; } finally { postResult(result); } return result; } };
调用call()方法的同时,我们终于看到了doInBackground()方法。执行完doInBackground()方法我们拿到了result,然后可以看到执行一个postResult方法,我们在根据这个方法走下去看。
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
postResult调用了message.sendToTarget(),实际上是通过了Handler发送一个消息,这个时候线程也切换到了主线程。
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; } } }
此时,到这里AsyncTask流程基本走完了,执行完finish方法之后。就会调用onCancelled,否则就是onPostExecute();
最后总结:AysncTask方法一旦调用excute()就会去判断当前状态,state默认是PENGING,状态不太就会抛出异常,同时也证明了AsyncTask的确只能被调用一次,判断完之后就会将状态置为Running,然后就会执行onPreExcute();开启一个线程去执行doInBackground();在doInBackground()执行完之后,会利用Handler去发送一个Message切换到主线程,然后执行onPostExcute();最后把状态置为finish。