美文网首页
AsyncTask源码解析

AsyncTask源码解析

作者: youseewhat | 来源:发表于2018-06-19 20:35 被阅读5次

AsyncTask

执行轻量级的异步任务,将结果传递给主线程,主线程根据结果更新UI.

使用

  • AsyncTask创建、启动都是在主线程中进行.

AsyncTask<URL, Integer, Long> asyncTask = new AsyncTask<URL, Integer, Long>() {
            //以下方法顺序就是调用顺序
            @Override
            protected void onPreExecute() {
                //主线程运行,异步任务开始的准备工作
                super.onPreExecute();
            }

            @Override
            protected Long doInBackground(URL... urls) {
                //在线程池中执行异步任务
                publishProgress();//更新任务进度,通过handler调用onProgressUpdate
                return null;
            }

            @Override
            protected void onProgressUpdate(Integer... values) {
                //主线程运行,异步进度改变就会调用
                super.onProgressUpdate(values);
            }

            @Override
            protected void onPostExecute(Long aLong) {
                //住线程运行,异步任务结束后被调用,aLong参数就是doInBackground的返回结果
                super.onPostExecute(aLong);
            }

            //另外还提供了异步任务取消的方法
            @Override
            protected void onCancelled() {
                super.onCancelled();
            }

            //取消建议调用该方法,
            @Override
            protected void onCancelled(Long aLong) {
                //运行在主线程。用于任务的取消
                super.onCancelled(aLong);
            }
        };

  • AsyncTask异步任务的启动、取消
//execute()必须在主线程调用,只能调用一次,多次调用会报错
//想要多次调用就得创建新的asyncTask
//execute()是串行执行
asyncTask.execute();
//并行执行调用方法
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

源码分析

看一下AsyncTask的源码就发现底层实现2个线程池、1个handler.核心线程池THREAD_POOL_EXECUTOR完成实际的任务执行,IntenalHandler完成线程间的切换.

  • 线程池的配置
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//核心线程数2-4个
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;
//线程任务队列容量为128
private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);
//线程工厂,生成AsyncTask # + *名的线程
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());
        }
    };
--------------------------------------------------------------------------------
执行的线程池决定了任务的执行方式
--------------------------------------------------------------------------------

/**并行线程池
 * An {@link Executor} that can be used to execute tasks in parallel.
 */
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;
}

/**串行线程池
     * An {@link Executor} that executes tasks one at a time in serial
     * order.  This serialization is global to a particular process.
     */
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static class SerialExecutor implements Executor {
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        Runnable mActive;
 //SerialExecutor相当于给任务线程排队
        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真正的任务执行者
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

  • Handler的创建和作用
可以清楚的看到在AsyncTask创建的时候sHandler就创建完成了,AsyncTask在主线程创建,
所以sHandler也在主线程,这就轻松实现了线程间的切换

private static InternalHandler sHandler;
private static Handler getMainHandler() {//静态代码随AsyncTask创建完成创建
        synchronized (AsyncTask.class) {
            if (sHandler == null) {
                sHandler = new InternalHandler(Looper.getMainLooper());
            }
            return sHandler;
        }
    }

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://调用publishProgress就会发送该消息
                //进度改变回调更新
                    result.mTask.onProgressUpdate(result.mData);
                    break;
            }
        }
    }

private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);//任务取消
        } else {
            onPostExecute(result);//任务完成
        }
        mStatus = Status.FINISHED;
    }

相关文章

  • Android AsyncTask 源码解析

    标签:Android AsyncTask 源码解析 1.关于AsyncTask 1.1 什么是AsyncTask?...

  • 4.AsyncTask使用,原理

    资料 AsyncTask处理机制详解及源码分析-工匠若水 AsyncTask 源码解析-鸿洋 带你认识不一样的As...

  • Android日记之AsyncTask源码解析

    前言 AsyncTask的使用方法请看Android日记之AsyncTask的基本使用,此篇的源码解析我们还是从使...

  • AsyncTask原理解析

    AsyncTask是一个串行的线程,本文主要通过源码解析它的原理 -->从 AsyncTask执行的方法execu...

  • AsyncTask 源码解析

    一、前言AsyncTask是一个异步任务。里面封装了线程池及Handler。所以,它可以方便地实现线程的切换及耗时...

  • AsyncTask源码解析

    参考资料:Android开发艺术探索 AsyncTask是一个Android官方提供的一种轻量级的异步任务类,它可...

  • AsyncTask源码解析

    AsyncTask 执行轻量级的异步任务,将结果传递给主线程,主线程根据结果更新UI. 使用 AsyncTask创...

  • AsyncTask源码解析

    AsyncTask源码解析 最近再刷一些基础的东西,所以就随便记录了一些看源码的心得,目前开发中见到了很多Asyn...

  • AsyncTask源码解析

    参考资料 鸿洋版AsyncTask郭霖版AsyncTask线程池Android开发艺术探索Android源码 相关...

  • AsyncTask源码解析

    变量 1. CPU_COUNT CPU总数 2. CORE_POOL_SIZE 核心线程数 3.MAXIMUM...

网友评论

      本文标题:AsyncTask源码解析

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