AsyncTask的学习java
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT(API level1.6), this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB(API level3.0), tasks are executed on a single thread to avoid common application errors caused by parallel execution. If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.android
1.6以前的AsyncTask在一个后台线程中串行serially,app
后来1.6之后又在一个线程池中并行.ide
再后来的3.0以后又只在一个线程中执行了.因此全部的AsyncTask都会排队.可是你也能够调用executeOnExecutor(Executor)传入你的线程池而后去并行这些任务.oop
AsyncTask为何后来要改为串行? 同一个进程中的AsyncTask使用的都是一个线程池.那么若是是并行的. 当A,B两个AsyncTask的doInbackGround方法都访问操做了同一个资源的话就煞笔了. 通常不会有人记得去synchronized一把doInbackground方法吧.
post
看这个东西是想知道为何刚开始AsyncTask的任务都是并行的?学习
public final AsyncTask<Params, Progress, Result> execute(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; sExecutor.execute(mFuture); return this; }
关于这个sExecutor的声明以下:因此很容易看出来这些任务都是在这个线程池中并行的.this
private static final int CORE_POOL_SIZE = 5; private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 10; private static final BlockingQueue<Runnable> sWorkQueue = new LinkedBlockingQueue<Runnable>(10); 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 ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
后来的代码变成了默认串行,是由于这段代码吗? synchronized致使这个方法只会同时有一个线程进入. 必须等这个线程执行完了才会释放锁让其余线程有机会进入execute方法. 那为何真正执行线程代码的地方线程池的核心线程要超过一个? 不是串行么?一个不就够了吗? ``` 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); } } } ```
android4.1.1
的代码.在ActivityThread这个类的main方法中有以下:线程
public static void main(String[] args) { ... AsyncTask.init(); }
这一样的4.1.1的AsyncTask的代码中code
首先这个sHandler的声明以下
private static final InternalHandler sHandler = new InternalHandler(); //Used to force static handler to be created. public static void init() { sHandler.getLooper(); }
这个InternalHandler是AsyncTask的一个内部类的代码以下:
private static class InternalHandler extends Handler { @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; } } }
可是在5.1(API level22)
之后这些有一点点变化 首先AsyncTask的init静态方法被去除了. 而后就是sHandler在声明的时候是空,后续操做该handler都经过getHander()方法.
private static InternalHandler sHandler; private static Handler getHandler() { //这里为啥不像double check似的写啊. synchronized (AsyncTask.class) { if (sHandler == null) { sHandler = new InternalHandler(); } return sHandler; } }
而后这个InternalHandler的内容和以前有了一个点小小的改变
private static class InternalHandler extends Handler { //这里是重点确保该handler的looper为主线程的looper 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; } } }
注意这个构造方法super(Looper.getMainLooper())这个就确保了这个sHandler的Looper必定是主线程的Looper. 那么经过这个sHandler发送的消息的handleMessage方法必定在主线程执行. 因此在这个时候after API level22
继承AsyncTask的实例就无需在主线程实例化了.
AsyncTask的构造方法代码
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); } } }; } private final WorkerRunnable<Params, Result> mWorker; private final FutureTask<Result> mFuture;
这里的WorkRunnable代码以下:
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }
可见这就是一个Callable. 下面开始跟踪代码.从
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
这个sDefaultExecutor的声明是这个样子:
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
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就是上面的sDefaultExecutor //mFuture就是构造方法建立的那个FutureTask exec.execute(mFuture); return this; }
而后再到SerialExecutor
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(); } } }); //A start if (mActive == null) { scheduleNext(); } //A end } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } }
SerialExecutor原本就是串行的线程池的意思. 它只负责把runnable放到mTasks中. execute方法中把new的runnable加入mTasks. 至于这个runnnable执行的内容先无论. 而后就到了代码段A.刚开始的时候mActive变量必须是null因此会执行scheduleNext()方法.而后这个方法里会从mTasks中取出东西并赋值给mActive变量. 并把这个mActive放到THREAD_POOL_EXECUTOR中执行.
到这里会先直接调用传入Runnable的run方法. 就是执行mFuture的run方法.
大概的了解:FutureTask实现了Runnnable接口.调用run方法会致使 构造该FutureTask的callable的call方法被调用.
因此到了这里构造方法中的WorkerRunnable的call方法就会被调用.该call方法以下:
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); }
到了这里AsyncTask的doInBackground(mParams)方法就被调用了.并且是在THREAD_POOL_EXECUTOR这个线程池中执行.
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); 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);
而后接着的代码
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
把doInbackground方法的结果经过handler进行发送.而后看handler的handleMessage方法.
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; } }
这里的result.mTask就是AsyncTask.见代码
private static class AsyncTaskResult<Data> { final AsyncTask mTask; final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } }
因此代码就到了AsyncTask的finish方法.
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
到这里就看到onPostExecute方法里,就差很少了.