2、假设你这样运行
new MyAsyncTask("MyAsyncTask#1").execute(); new MyAsyncTask("MyAsyncTask#2").execute(); new MyAsyncTask("MyAsyncTask#3").execute(); new MyAsyncTask("MyAsyncTask#4").execute(); new MyAsyncTask("MyAsyncTask#5").execute(); new MyAsyncTask("MyAsyncTask#6").execute();3、你觉得会发生什么呢?
在Android3.0之前执行的时间是一样的,在Android3.0之后每个执行时间相差2秒android3.0虽然已经基本不用适配了,但是我们了解一下还是不错的哦我先我们看到一个@MainThread的注解。╮(╯_╰)╭这是什么东东呢?我没用过呢。
其实它是google提供的一个注解,标注我们的这个方法必须在主线程中调用,如果不是的话,AS就会红色提示我们哦。
然后我们可以看到,execute里面其实是执行了executeOnExecutor方法,他传入了两个参数:1、sDefaultExecutor(这是干什么的呢?)2、params 从execute传递下来的可变参数,OK,重点就是sDefaultExecutor了,从名字上看sDefaultExecutor是个磨人的执行器的意思,但我们是很较真的人,所以必须看下sDefaultExecutor是个什么东东( ̄∇ ̄),所以就逗逼逗逼的去找相关代码了 public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;Ok,从其定义的地方可以看到,sDefaultExecutor是一个Executor类型的实例,通过SerialExecutor()获得。我们下看SerialExecutor()里面都做了什么?
private static class SerialExecutor implements Executor { //1、线程队列 final ArrayDeque mTasks = new ArrayDeque(); //2、当前执行的线程 Runnable mActive; public synchronized void execute(final Runnable r) { //3、创建一个新的runable入队列 mTasks.offer(new Runnable() { public void run() { try { //5、这里有点绕,首先新创建的runnable会先调用我们外部的runnable,外部的runnable执行完了再调用scheduleNext(),外部的runnable其实就是我们调用时传入的runnable,我们在线程中编写的代码在调用r.run()时开始执行。mTasks中的runnable只是对我们的runnable做了一次包装 r.run(); } finally { scheduleNext(); } } }); //4、如果当前没有正在执行的线程任务,则马上调用scheduleNext()方法取出队列中的runnable并运行。 if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { //6、线程出队列,如果队列部位空,就通过THREAD_POOL_EXECUTOR.execute(mActive);线程池执行runable。 if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } } 从上面代码可以看到,里面有一个mTasks的数组队列。当我们调用Execute的时候就会在mTasks队列中插入一个runnable实例,也就是说,mTasks里面存放的是线程,可能你会很奇怪,首先这里public synchronized void execute(final Runnable r)传如了一个runnable,然后这里mTasks.offer(new Runnable() 又创建一个新的runnable入队列。OK,更详细的分析我放到了代码中OK我们继续回到executeOnExecutor方法 @MainThread public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { //1、判断任务是否没有被执行过,mStatus != Status.PENDING为true为被执行过,这也就是前面说的execute只能执行一次的原因,如果执行过下面会报运行时异常 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)"); } } //2、设置任务状态为正在执行 mStatus = Status.RUNNING; //3、先调用onPreExecute方法 onPreExecute(); mWorker.mParams = params; //4、通过执行器调用我 exec.execute(mFuture); return this; }Ok,我们来进一步分析下AsyncTask的执行过程,首先我们看下AsyncTask的构造方法都做了什么
public AsyncTask() { //1、 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; } }; //2、 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); } } }; }1处:创建一个WorkerRunnable,注意第二个泛型参数Result,这个就是我们继承AsyncTask时传递的第三个参数哦,然后里面看到调用了result = doInBackground(mParams);最终都会调用postResult(result);方法
2处:创建一个FutureTask的对象,mFuture就是我们前面executeOnExecutor方能发中最重调用exec.execute(mFuture);传入的参数哦,说明mFuture是个runnable类型的实例。然后把mWorker传入创建,说明runable执行的是mWorker里面的工作,yes,所以我们的doInBackground方法是在runable线程中执行的OK,我们之前只说了我们的代码是如何放入子线程中的,但是并没有看见启动子线程的代码啊?我们可以看奥,他最终都调用的postResult方法 private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; } Ok,可以看到,里面是通过我们熟悉的Handler来进行实现的哦。我们看他他传入了MESSAGE_POST_RESULT和AsyncTaskResult,this就是我们的AsyncTask了,后面应该是在handler中调用了AsyncTask的某个方法,我们看下getHandler() private static Handler getHandler() { synchronized (AsyncTask.class) { if (sHandler == null) { sHandler = new InternalHandler(); } return sHandler; } } OK,里面是一个InternalHandler实例。而InternalHandler是这样的 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; } } }OK,里面看到了MESSAGE_POST_RESULT对应的是finish方法。也就是我们的AsyncTask的finish方法
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }可以看到,里面最终会调用onCancelled(result);或者onPostExecute(result);
/** * An {@link Executor} that can be used to execute tasks in parallel. */ public static final Executor THREAD_POOL_EXECUTOR;
看到这里我有点郁闷了,前面在分析SerialExecutor是,里面不也是将runable让入THREAD_POOL_EXECUTOR中执行么?
SerialExecutor为什么是串行呢?虽然也是放入THREAD_POOL_EXECUTOR中,但是他是从队列中取出来放入的哦,而且一次只取出一个,执行完再取第二个