• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > 源码解析Android中AsyncTask的工作原理

源码解析Android中AsyncTask的工作原理

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了asynctask源码,asynctask源码分析,android asynctask,android中asynctask,android.os.asynctask等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

源码解析Android中AsyncTask的工作原理


在之前的博客《Android中AsyncTask使用详解》中我们提到AsyncTask是对Thread和Handler的组合包装,本文将通过解析的方式让大家了解AsyncTask的工作原理。

AsyncTask的源码链接https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/AsyncTask.java

AsyncTask一开始定义了一些字段,如下所示:

private static final String LOG_TAG = "AsyncTask";

    //CPU_COUNT为手机中的CPU核数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    //将手机中的CPU核数加1作为AsyncTask所使用的线程池的核心线程数的大小
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    //将CPU_COUNT * 2 + 1作为AsyncTask所使用的线程池的最大线程数的大小
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE = 1;

    //实例化线程工厂ThreadFactory,sThreadFactory用于在后面创建线程池
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        //mCount为AtomicInteger类型,AtomicInteger是一个提供原子操作的Integer类,
        //确保了其getAndIncrement方法是线程安全的
        private final AtomicInteger mCount = new AtomicInteger(1);

        //重写newThread方法的目的是为了将新增线程的名字以"AsyncTask #"标识
        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };

    //实例化阻塞式队列BlockingQueue,队列中存放Runnable,容量为128
    private static final BlockingQueue sPoolWorkQueue =
            new LinkedBlockingQueue(128);

    //根据上面定义的参数实例化线程池
    public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

通过以上代码和注释我们可以知道,AsyncTask初始化了一些参数,并用这些参数实例化了一个线程池THREAD_POOL_EXECUTOR,需要注意的是该线程池被定义为public static final,由此我们可以看出AsyncTask内部维护了一个静态的线程池,默认情况下,AsyncTask的实际工作就是通过该THREAD_POOL_EXECUTOR完成的。

我们继续,在执行完上面的代码后,AsyncTask又有如下一条语句:

public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

上面的代码实例化了一个SerialExecutor类型的实例SERIAL_EXECUTOR,它也是public static final的。SerialExecutor是AsyncTask的一个内部类,代码如下所示:

//SerialExecutor实现了Executor接口中的execute方法,该类用于串行执行任务,
    //即一个接一个地执行任务,而不是并行执行任务
    private static class SerialExecutor implements Executor {
        //mTasks是一个维护Runnable的双端队列,ArrayDeque没有容量限制,其容量可自增长
        final ArrayDeque mTasks = new ArrayDeque();
        //mActive表示当前正在执行的任务Runnable
        Runnable mActive;

        public synchronized void execute(final Runnable r) {
            //execute方法会传入一个Runnable类型的变量r
            //然后我们会实例化一个Runnable类型的匿名内部类以对r进行封装,
            //通过队列的offer方法将封装后的Runnable添加到队尾
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        //执行r的run方法,开始执行任务
                        //此处r的run方法是在线程池中执行的
                        r.run();
                    } finally {
                        //当任务执行完毕的时候,通过调用scheduleNext方法执行下一个Runnable任务
                        scheduleNext();
                    }
                }
            });
            //只有当前没有执行任何任务时,才会立即执行scheduleNext方法
            if (mActive == null) {
                scheduleNext();
            }
        }

        protected synchronized void scheduleNext() {
            //通过mTasks的poll方法进行出队操作,删除并返回队头的Runnable,
            //将返回的Runnable赋值给mActive,
            //如果不为空,那么就让将其作为参数传递给THREAD_POOL_EXECUTOR的execute方法进行执行
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }

通过以上代码和注释我们可以知道:

SerialExecutor实现了Executor接口中的execute方法,该类用于串行执行任务,即一个接一个地执行任务,而不是并行执行任务。

SerialExecutor内部维护了一个存放Runnable的双端队列mTasks。当执行SerialExecutor的execute方法时,会传入一个Runnable变量r,但是mTasks并不直接存储r,而是又新new了一个匿名Runnable对象,其内部会调用r,这样就对r进行了封装,将该封装后的Runnable对象通过队列的offer方法入队,添加到mTasks的队尾。

SerialExecutor内部通过mActive存储着当前正在执行的任务Runnable。当执行SerialExecutor的execute方法时,首先会向mTasks的队尾添加进一个Runnable。然后判断如果mActive为null,即当前没有任务Runnable正在运行,那么就会执行scheduleNext()方法。当执行scheduleNext方法的时候,会首先从mTasks中通过poll方法出队,删除并返回队头的Runnable,将返回的Runnable赋值给mActive,如果不为空,那么就让将其作为参数传递给THREAD_POOL_EXECUTOR的execute方法进行执行。由此,我们可以看出SerialExecutor实际上是通过之前定义的线程池THREAD_POOL_EXECUTOR进行实际的处理的。

当将mTasks中的Runnable作为参数传递给THREAD_POOL_EXECUTOR执行execute方法时,会在线程池的工作线程中执行匿名内部类Runnable中的try-finally代码段,即先在工作线程中执行r.run()方法去执行任务,无论任务r正常完成还是抛出异常,都会在finally中执行scheduleNext方法,用于执行mTasks中的下一个任务。从而在此处我们可以看出SerialExecutor是一个接一个执行任务,是串行执行任务,而不是并行执行。

AsyncTask内部定义了一个Status枚举类型,如下所示:

public enum Status {
        //PENDING表示还没有开始执行任务
        PENDING,
        //RUNNING表示已经开始执行任务
        RUNNING,
        //FINISHED表示任务已经执行完成或被取消了,总之onPostExecute方法已经被调用了
        FINISHED,
    }

一个AsyncTask正常情况下会经历PENDING->RUNNING->FINISHED三个状态。

AsyncTask还定义了以下字段:

//用于通过Handler发布result的Message Code
    private static final int MESSAGE_POST_RESULT = 0x1;
    //用于通过Handler发布progress的Message Code
    private static final int MESSAGE_POST_PROGRESS = 0x2;

    //sDefaultExecutor表示AsyncTask默认使用SERIAL_EXECUTOR作为Executor,
    //即默认情况下AsyncTask是串行执行任务,而不是并行执行任务
    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

    //InternalHandler是AsyncTask中定义的一个静态内部类,其绑定了主线程的Looper和消息队列
    private static InternalHandler sHandler;

    //mWorker是一个实现了Callable接口的对象,其实现了Callable接口的call方法
    private final WorkerRunnable mWorker;
    //根据mFuture是一个FutureTask对象,需要用mWorker作为参数实例化mFuture
    private final FutureTask mFuture;

    //AsyncTask的初始状态位PENDING
    private volatile Status mStatus = Status.PENDING;

    //mCancelled标识当前任务是否被取消了
    private final AtomicBoolean mCancelled = new AtomicBoolean();
    //mTaskInvoked标识当前任务是否真正开始执行了
    private final AtomicBoolean mTaskInvoked = new AtomicBoolean();

我们对以上代码再进行一下说明:

sDefaultExecutor表示AsyncTask执行任务时默认所使用的线程池,sDefaultExecutor的初始值为SERIAL_EXECUTOR,表示默认情况下AsyncTask是串行执行任务,而不是并行执行任务。

InternalHandler是AsyncTask中定义的一个静态内部类,其部分源码如下所示:

private static class InternalHandler extends Handler {
    public InternalHandler() {
        //Looper类的getMainLooper方法是个静态方法,该方法返回主线程的L



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android中AsyncTask基本用法与源码剖析(API 23)
  • android源码解析之(二)--)异步任务AsyncTask
  • AsyncTask源码探究,asynctask源码
  • 源码解析Android中AsyncTask的工作原理

相关文章

  • 2017-05-26Activity生命周期,activity生命周期图
  • 2017-05-26android 关于4.0之后不能直接获取SD卡外部存储路径的问题,androidsd
  • 2017-05-26多线程中使用curl致coredump问题
  • 2017-05-26Linux简介及常用命令使用5--linux shell编程入门,5--linux编程入门
  • 2017-05-26Linux 新的API signalfd、timerfd、eventfd使用说明
  • 2017-05-26安卓生成二维码 ==。以及中文乱码问题,安卓生成中文乱码
  • 2017-05-26Android中AsyncTask基本用法与源码剖析(API 23)
  • 2017-05-26Listview详解,listview
  • 2017-05-26EventBus初理解,EventBus理解
  • 2017-05-26not allowed to access to crontab because of pam configuration

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • android http同步请求,android同步请求
    • Android开发:优化ListView实践解析
    • 8.2.1 Bitmap(位图)全解析 Part 1
    • 硅谷新闻7--顶部轮播图循环播放,7--循环播放
    • Android Material Design NavigationView 及 Palette 颜色提取器,materialpalette
    • did not call through to super.onCreate(),didsuper.oncreate
    • Android 关于“NetworkOnMainThreadException”,networkonmainthread
    • MVP模式在Android开发中的最佳实践
    • 深入浅出《Unix环境高级编程》:Unix基础知识(三)
    • 自定义控件详解(二):Path类 相关用法,详解path

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有