美文网首页
Android多线程:AsyncTask的源码解析

Android多线程:AsyncTask的源码解析

作者: 柳岸风语 | 来源:发表于2019-02-23 21:45 被阅读0次
    boat.jpg

    AsyncTask作为Android原生的一个异步加载类,在前几年还是非常流行的,但随着RxJava和RxAndroid的流行,它的吸引力降低了不少。AsyncTask是通过对ThreadHandler的封装,简化我们的操作,满足我们在线程里面进行计算,在主线程更新UI。但是AsyncTask适用于短时操作(最多几秒钟),并不推荐用于长时间的耗时操作(现在版本的AsyncTask任务的执行是串行,当然也可以自己选并行)。

    AsyncTask的使用还是非常简单的,下面就是使用的例子:

    public class MyAsyncTask extends AsyncTask<String, Integer, String> {
    
        /**
         * 运行异步线程的任务
         * @param strings
         * @return
         */
        @Override
        protected String doInBackground(String... strings) {
            return null;
        }
    
        /**
         * 运行在主线程,接受异步线程任务的结果
         * @param s
         */
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
        }
    
        /**
         * 运行在主线程,在异步线程执行前执行,可以做一些准备工作
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
    
        /**
         * 
         * 运行在主线程,加载进度
         * @param values
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }
    
    /**
         * 运行在主线程,取消监听
         */
        @Override
        protected void onCancelled() {
            super.onCancelled();
        }
    }
    new MyAsyncTask().execute("执行");
    

    使用起来就是如此的简单爽快。

    AsyncTask的源码分析:

        public abstract class AsyncTask<Params, Progress, Result> {
        private static final String LOG_TAG = "AsyncTask";
    
        //CPU数量
        private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
        //线程池核心线程数量,最多4个,最少2个
        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;
        //空闲线程的存活时间30s
        private static final int KEEP_ALIVE_SECONDS = 30;
    
        //线程池创建线程的线程工厂
        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());
            }
        };
    
        //静态阻塞式队列,用来存放待执行的任务,初始容量为128
        //这个阻塞式队列很特别类,主要提供了两个方法put()和take(),
        // 前者将一个对象放到队列中,如果队列已经满了,就等待直到有空闲节点;
        // 后者从head取一个对象,如果没有对象,就等待直到有可取的对象
        private static final BlockingQueue<Runnable> sPoolWorkQueue =
                new LinkedBlockingQueue<Runnable>(128);
    
        //静态并行执行器,3.0以前这是AsyncTask的默认执行器
        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;
        }
    
        //静态串行执行器,内部进行了串行控制,可以不断的递归任务执行
        public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
    
        //Handler的消息类型,发送结果
        private static final int MESSAGE_POST_RESULT = 0x1;
        //Handler的消息类型,发送进度
        private static final int MESSAGE_POST_PROGRESS = 0x2;
    
        //默认执行器,从3.0开始,默认使用串行
        private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
        //静态Handler,使用懒加载方式,使用时才创建,而且使用了单例模式
        private static InternalHandler sHandler;
    
        //任务执行相关的两个类
        private final WorkerRunnable<Params, Result> mWorker;
        private final FutureTask<Result>             mFuture;
    
        //当前状态,默认是未执行状态
        private volatile android.os.AsyncTask.Status mStatus = android.os.AsyncTask.Status.PENDING;
    
        //是否取消
        private final AtomicBoolean mCancelled   = new AtomicBoolean();
        //任务是否被执行
        private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
    
        //用于执行消息发送的Handler, 默认是把sHandler赋值给他
        private final Handler mHandler;
    
        //静态串行执行器类
        private static class SerialExecutor implements Executor {
            //一个既可以用于队列又可以用于栈的类,它的执行速度比LinkList和Stack快;
            //这个是用于队列
            final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
            //当前正在执行的任务
            Runnable mActive;
    
            public synchronized void execute(final Runnable r) {
                mTasks.offer(new Runnable() {
                    public void run() {
                        //下面这段代码保证了串行的执行机制,使用try{}finally{}模式,也是十分有想象力的
                        try {
                            r.run();
                        } finally {
                            scheduleNext();
                        }
                    }
                });
                if (mActive == null) {
                    scheduleNext();
                }
            }
    
            protected synchronized void scheduleNext() {
                if ((mActive = mTasks.poll()) != null) {
                    THREAD_POOL_EXECUTOR.execute(mActive);
                }
            }
        }
    
        public enum Status {
            // 当前还未执行任务,正在等待任务加入
            PENDING,
            // 当前正在执行任务
            RUNNING,
            //任务执行完成(标志onPostExecute完成)
            FINISHED,
        }
    
        private static Handler getMainHandler() {
            synchronized (android.os.AsyncTask.class) {
                if (sHandler == null) {
                    //保证了Hanlder的执行是在主线程
                    sHandler = new InternalHandler(Looper.getMainLooper());
                }
                return sHandler;
            }
        }
    
        private Handler getHandler() {
            return mHandler;
        }
    
        //可以用于切换执行器,使用并行方式,这方法被隐藏了,官方希望我们使用默认方式
        public static void setDefaultExecutor(Executor exec) {
            sDefaultExecutor = exec;
        }
    
        public AsyncTask() {
            this((Looper) null);
        }
    
        public AsyncTask(@Nullable Handler handler) {
            this(handler != null ? handler.getLooper() : null);
        }
    
        public AsyncTask(@Nullable Looper callbackLooper) {
            //以前AsyncTask要求初始化一定要放在主线程,现在没这个要求了
            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);
                        //这里异步任务被执行,返回结果
                        result = doInBackground(mParams);
                        Binder.flushPendingCommands();
                    } catch (Throwable tr) {
                        mCancelled.set(true);
                        throw tr;
                    } finally {
                        //结果返回
                        postResult(result);
                    }
                    return result;
                }
            };
    
            mFuture = new FutureTask<Result>(mWorker) {
                //mWorker的Call()执行完后,再执行,这里主要处理异常情况,如被取消
                @Override
                protected void done() {
                    try {
                        //get()方法是一个阻塞方法,直到mWorker的Call()执行有结果后才会执行
                        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 void postResultIfNotInvoked(Result result) {
            final boolean wasTaskInvoked = mTaskInvoked.get();
            if (!wasTaskInvoked) {//正常情况下,wasTaskInvoked为true
                postResult(result);
            }
        }
    
        //Handler发送结果消息
        private Result postResult(Result result) {
            @SuppressWarnings("unchecked")
            Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                    new AsyncTaskResult<Result>(this, result));
            message.sendToTarget();
            return result;
        }
    
        public final android.os.AsyncTask.Status getStatus() {
            return mStatus;
        }
    
        //执行在线程里面,用于需要重写
        @WorkerThread
        protected abstract Result doInBackground(Params... params);
    
        //执行在主线程,运行在doInBackground前面,可以做一些准备工作,如进度条的初始化
        @MainThread
        protected void onPreExecute() {
        }
    
        //执行在主线程,子线程处理得到的结果
        @SuppressWarnings({"UnusedDeclaration"})
        @MainThread
        protected void onPostExecute(Result result) {
        }
    
        //执行在主线程,处理进度
        @SuppressWarnings({"UnusedDeclaration"})
        @MainThread
        protected void onProgressUpdate(Progress... values) {
        }
    
        //执行在主线程,任务取消,这个方法,用户不应该自己调用
        @SuppressWarnings({"UnusedParameters"})
        @MainThread
        protected void onCancelled(Result result) {
            onCancelled();
        }
    
        //执行在主线程,任务取消
        @MainThread
        protected void onCancelled() {
        }
    
        //任务是否被取消
        public final boolean isCancelled() {
            return mCancelled.get();
        }
    
        //取消任务
        public final boolean cancel(boolean mayInterruptIfRunning) {
            mCancelled.set(true);
            return mFuture.cancel(mayInterruptIfRunning);
        }
    
        public final Result get() throws InterruptedException, ExecutionException {
            return mFuture.get();
        }
    
        public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
                ExecutionException, TimeoutException {
            return mFuture.get(timeout, unit);
        }
    
        //任务执行
        @MainThread
        public final android.os.AsyncTask<Params, Progress, Result> execute(Params... params) {
            return executeOnExecutor(sDefaultExecutor, params);
        }
    
        @MainThread
        public final android.os.AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
                                                                                      Params... params) {
            if (mStatus != android.os.AsyncTask.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 = android.os.AsyncTask.Status.RUNNING;
    
            //看这里,果然是先执行
            onPreExecute();
    
            mWorker.mParams = params;
            exec.execute(mFuture);
    
            return this;
        }
    
        //还可以直接执行Runnable
        @MainThread
        public static void execute(Runnable runnable) {
            sDefaultExecutor.execute(runnable);
        }
    
        @WorkerThread
        protected final void publishProgress(Progress... values) {
            if (!isCancelled()) {
                getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                        new AsyncTaskResult<Progress>(this, values)).sendToTarget();
            }
        }
        
        private void finish(Result result) {
            if (isCancelled()) {
                onCancelled(result);//如果取消了,走取消监听
            } else {
                onPostExecute(result);//否则,发布计算结果
            }
            //从这里可以看出,onCancelled和onPostExecute是互斥的
            mStatus = android.os.AsyncTask.Status.FINISHED;
        }
    
        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;
                }
            }
        }
    
        private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
            Params[] mParams;
        }
    
        @SuppressWarnings({"RawUseOfParameterizedType"})
        private static class AsyncTaskResult<Data> {
            final android.os.AsyncTask mTask;
            final Data[]               mData;
    
            AsyncTaskResult(android.os.AsyncTask task, Data... data) {
                mTask = task;
                mData = data;
            }
        }
    }
    

    总结:
    1、AsyncTask其实只是对Thread和Handler进行了一些封装;
    2、AsyncTask默认使用的是串行的执行方式,这就要求我们不要去执行太耗时的任务,官方告诉我们执行时间最好是几秒;
    3、我们可以手动将AsyncTask的执行方式改为并行执行,方法是executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Params... params)

    相关文章

      网友评论

          本文标题:Android多线程:AsyncTask的源码解析

          本文链接:https://www.haomeiwen.com/subject/jmdimftx.html