AsyncTask8.0源码分析

 

public abstract class AsyncTask<Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";

    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;

 private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);

.......................
}

在这里又看到了ThreadPoolExecutor,它的核心线程数是Math.max(2, Math.min(CPU_COUNT - 1, 4))个,线程池允许创建的最大线程数为CPU_COUNT * 2 + 1,非核心线程空闲等待新任务的最长时间为10秒。采用的阻塞队列是LinkedBlockingQueue,它的容量为128。3.0版本之前的AsyncTask有一个缺点就是,线程池最大的线程数为MAXIMUM_POOL_SIZE,加上阻塞队列的128个任务,所以AsyncTask最多能同时容纳128+MAXIMUM_POOL_SIZE个任务,当提交第128+MAXIMUM_POOL_SIZE+1任务时就会执行饱和策略,默认抛出RejectedExecutionException异常。

 public AsyncTask(@Nullable Looper callbackLooper) {

        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()

            ? getMainHandler()

            : new Handler(callbackLooper);

 

        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;

            }

        };

 

        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);

                }

            }

        };

    }

WorkerRunnable实现了Callable接口,在call中调用了doInBackground(mParams),最终调用postResult(result)。 FutureTask是一个可管理的异步任务,它实现Runnable和Future接口,它可以包装Runnable和Callable接口,给Executor执行。在这里 WorkerRunnable作为参数传给FutureTask,稍后会用到。执行会调用execute方法:

 @MainThread

    public final AsyncTask<Params, Progress, Result> execute(Params... params) {

        return executeOnExecutor(sDefaultExecutor, params);

    }

 

execute方法又调用executeOnExecutor方法:

    @MainThread

    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;

    }

这里先调用 onPreExecute方法,这里exec是传进来sDefaultExecutor,它是一个串行线程池:

    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);

            }

        }

    }

调用SerialExecutor的execute方法时,会将FutureTask加入到mTask中。最后执行 scheduleNext方法,他会从mTasks取出FutureTask交给 THREAD_POOL_EXECUTOR处理。

   public static final Executor THREAD_POOL_EXECUTOR;

 

    static {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(

                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,

                sPoolWorkQueue, sThreadFactory);

        threadPoolExecutor.allowCoreThreadTimeOut(true);

        THREAD_POOL_EXECUTOR = threadPoolExecutor;

    }

从这里看出,serialExecutor是串行执行的。可以看到会执行FutureTask的run方法,最终执行WorkerRunnable的call方法。最终调用postResult方法:

    private Result postResult(Result result) {

        @SuppressWarnings("unchecked")

        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,

                new AsyncTaskResult<Result>(this, result));

        message.sendToTarget();

        return result;

    }

最终调用Handler:

    private static class InternalHandler extends Handler {

        public InternalHandler(Looper looper) {

            super(looper);

        }

 

        @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;

            }

        }

在接收到MESSAGE_POST_RESULT,会调用finish方法

    private void finish(Result result) {

        if (isCancelled()) {

            onCancelled(result);

        } else {

            onPostExecute(result);

        }

        mStatus = Status.FINISHED;

    }

  如果AsyncTask任务被取消了则执行onCancelled方法,否则就调用onPostExecute方法。而正是通过onPostExecute方法我们才能够得到异步任务执行后的结果。 接着回头来看SerialExecutor ,线程池SerialExecutor主要用来处理排队,将任务串行处理。 SerialExecutor中调用scheduleNext方法时,将任务交给THREAD_POOL_EXECUTOR。THREAD_POOL_EXECUTOR同样是一个线程池,用来执行任务。

  THREAD_POOL_EXECUTOR指的就是threadPoolExecutor,他的核心线程和线程池允许创建的最大线程数都是由CPU的核数来计算出来的。它采用的阻塞队列仍旧是LinkedBlockingQueue,容量为128。 

  到此, AsyncTask的源码就分析完了,在AsyncTask中用到了线程池,线程池中运行线程并且又用到了阻塞队列,因此,本章前面介绍的知识在这一节中做了很好的铺垫。Android 3.0及以上版本用SerialExecutor作为默认的线程,它将任务串行的处理保证一个时间段只有一个任务执行,而3.0之前版本是并行处理的。关于3.0之前版本的缺点在3.0之后版本也不会出现,因为线程是一个接一个执行的,不会出现超过任务数而执行饱和策略。

如果想要在3.0及以上版本使用并行的线程处理可以使用如下的代码:asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值