从AsyncTask的实现可以看出,当我们第一次创建一个AsyncTask对象时,首先会执行下面静态初始化代码创建一个线程池sExecutor:
  1. private static final BlockingQueue<Runnable> sWorkQueue =   
  2.     new LinkedBlockingQueue<Runnable>(10);   
  3.    
  4. private static final ThreadFactory sThreadFactory = new ThreadFactory() {   
  5.     private final AtomicInteger mCount = new AtomicInteger(1);   
  6.    
  7.     public Thread newThread(Runnable r) {   
  8.         return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());   
  9.     }   
  10. };   
  11.    
  12. ......   
  13.    
  14. private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,   
  15.     MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);   
这里的ThreadPoolExecutor是Java提供的多线程机制之一,这里用的构造函数原型为: 
  1. ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,    
  2.     BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)   
 各个参数的意义如下:
        corePoolSize -- 线程池的核心线程数量
        maximumPoolSize -- 线程池的最大线程数量
        keepAliveTime -- 若线程池的线程数数量大于核心线程数量,那么空闲时间超过keepAliveTime的线程将被回收
        unit -- 参数keepAliveTime使用的时间单位
        workerQueue -- 工作任务队列
        threadFactory -- 用来创建线程池中的线程
        简单来说,ThreadPoolExecutor的运行机制是这样的:每一个工作任务用一个Runnable对象来表示,当我们要把一个工作任务交给这个线程池来执行的时候,就通过调用ThreadPoolExecutor的execute函数来把这个工作任务加入到线程池中去。此时,如果线程池中的线程数量小于corePoolSize,那么就会调用threadFactory接口来创建一个新的线程并且加入到线程池中去,再执行这个工作任务;如果线程池中的线程数量等于corePoolSize,但是工作任务队列workerQueue未满,则把这个工作任务加入到工作任务队列中去等待执行;如果线程池中的线程数量大于corePoolSize,但是小于maximumPoolSize,并且工作任务队列workerQueue已经满了,那么就会调用threadFactory接口来创建一个新的线程并且加入到线程池中去,再执行这个工作任务;如果线程池中的线程量已经等于maximumPoolSize了,并且工作任务队列workerQueue也已经满了,这个工作任务就被拒绝执行了。
        创建好了线程池后,再创建一个消息处理器:
  1. private static final InternalHandler sHandler = new InternalHandler();   
 注意,这行代码是在应用程序的主线程中执行的,因此,这个消息处理器sHandler内部引用的消息循环对象looper是应用程序主线程的消息循环对象,消息处理器的实现机制具体可以参考前面一篇文章Android应用程序消息处理机制(Looper、Handler)分析。
        AsyncTask类的静态初始化代码执行完成之后,才开始创建AsyncTask对象,即执行AsyncTask类的构造函数:
  1. public AsyncTask() {   
  2.     mWorker = new WorkerRunnable<Params, Result>() {   
  3.         public Result call() throws Exception {   
  4.             ......   
  5.             return doInBackground(mParams);   
  6.         }   
  7.     };   
  8.    
  9.     mFuture = new FutureTask<Result>(mWorker) {   
  10.         @Override   
  11.         protected void done() {   
  12.             Message message;   
  13.             Result result = null;   
  14.    
  15.             try {   
  16.                 result = get();   
  17.             } catch (InterruptedException e) {   
  18.                 android.util.Log.w(LOG_TAG, e);   
  19.             } catch (ExecutionException e) {   
  20.                 throw new RuntimeException("An error occured while executing doInBackground()",   
  21.                     e.getCause());   
  22.             } catch (CancellationException e) {   
  23.                 message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,   
  24.                     new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));   
  25.                 message.sendToTarget();   
  26.                 return;   
  27.             } catch (Throwable t) {   
  28.                 throw new RuntimeException("An error occured while executing "   
  29.                     + "doInBackground()", t);   
  30.             }   
  31.    
  32.             message = sHandler.obtainMessage(MESSAGE_POST_RESULT,   
  33.                 new AsyncTaskResult<Result>(AsyncTask.this, result));   
  34.             message.sendToTarget();   
  35.         }   
  36.     };   
  37. }   
  在AsyncTask类的构造函数里面,主要是创建了两个对象,分别是一个WorkerRunnable对象mWorker和一个FutureTask对象mFuture。
        WorkerRunnable类实现了Runnable接口,此外,它的内部成员变量mParams用于保存从AsyncTask对象的execute函数传进来的参数列表:
  1. private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {   
  2.     Params[] mParams;   
  3. }   
 FutureTask类也实现了Runnable接口,所以它可以作为一个工作任务通过调用AsyncTask类的execute函数添加到sExecuto线程池中去:
  1. public final AsyncTask<Params, Progress, Result> execute(Params... params) {   
  2.     ......   
  3.    
  4.     mWorker.mParams = params;   
  5.     sExecutor.execute(mFuture);   
  6.    
  7.     return this;   
  8. }   
这里的FutureTask对象mFuture是用来封装前面的WorkerRunnable对象mWorker。当mFuture加入到线程池中执行时,它调用的是mWorker对象的call函数:
  1. mWorker = new WorkerRunnable<Params, Result>() {   
  2.     public Result call() throws Exception {   
  3.            ......   
  4.            return doInBackground(mParams);   
  5.         }   
  6. };   
在call函数里面,会调用AsyncTask类的doInBackground函数来执行真正的任务,这个函数是要由AsyncTask的子类来实现的,注意,这个函数是在应用程序的子线程中执行的,它不可以操作应用程序的界面。

Android应用程序线程消息循环模型分析(5)相关推荐

  1. Android应用程序线程消息循环模型分析

    出自:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是通过消息来驱动的,即在应用程序的主线程(UI ...

  2. Android应用程序线程消息循环模型分析(4)

    接下来我们再看看应用程序的配置文件AndroidManifest.xml: <?xml version="1.0" encoding="utf-8"?&g ...

  3. QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数

    版权声明 请尊重原创作品.转载请保持文章完整性,并以超链接形式注明原始作者"tingsking18"和主站点地址,方便其他朋友提问和指正. QT源码解析(一) QT创建窗口程序.消 ...

  4. 记一次 .NET医院公众号程序 线程CPU双高分析

    一:背景 1. 讲故事 上周四有位朋友加wx咨询他的程序出现 CPU + 线程 双高的情况,希望我能帮忙排查下,如下图: 从截图看只是线程爆高,没看到 cpu 爆高哈????????????,有意思的 ...

  5. android 消息循环机制--looper handler

    Looper类说明   Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在run()方法中的内容执行完之后就退出了,即线程做完自己的工作之后就结 ...

  6. Android系统Surface机制的SurfaceFlinger服务的线程模型分析

    在前面两篇文章中,我们分析了SurfaceFlinger服务的启动过程以及SurfaceFlinger服务初始化硬件帧缓冲区的过程.从这两个过程可以知道,SurfaceFlinger服务在启动的过程中 ...

  7. Android的消息循环机制:Handler

    前言 Android的消息机制主要是指Handler的运行机制,对于大家来说Handler已经是轻车熟路了,可是真的掌握了Handler?本文主要通过几个问题围绕着Handler展开深入并拓展的了解. ...

  8. android 结束if循环_Android Handler 消息循环机制

    前言 一问起Android应用程序的入口,很多人会说是Activity中的onCreate方法,也有人说是ActivityThread中的静态main方法.因为Java虚拟机在运行的时候会自动加载指定 ...

  9. Android 应用程序消息处理机制(Looper、Handler)分析

    Android应用程序是通过消息来驱动的,系统为每一个应用程序维护一个消息队例,应用程序的主线程不断地从这个消息队例中获取消息(Looper),然后对这些消息进行处理(Handler),这样就实现了通 ...

最新文章

  1. 暑期集训5:并查集 线段树 练习题F:  HDU - 1166 ​​​​​​​
  2. C++判断字符串中是否有中文
  3. python如何读取excel数据-python怎么从excel中读取数据?
  4. C++中的c_str()函数用法
  5. Java集合:HashMap
  6. c语言仿ce内存搜索工 源代码_C语言函数库:动态库和静态库优缺点比较
  7. 使用sql语句创建和删除约束示例代码
  8. bzoj4515 [Sdoi2016]游戏 标记永久线段树+链剖+差分
  9. mysql参数积累 持续更新。。。
  10. SourceTree的使用
  11. Servlet JSP - 转发与重定向的区别
  12. 第一次作业+105032014140
  13. 照相长度测试软件,拍张照片就知道你的长度了,还要什么测量工具!
  14. 推荐五个免费UML建模工具
  15. OpenKG开源系列 | 轻量级知识图谱抽取开源工具OpenUE
  16. android仿ios消息框,Android仿IOS提示框
  17. 如何绘制变参数根轨迹(针对复杂情况,无法分离出开环增益k*时)
  18. 随机森林和多元线性回归R语言实现代码
  19. 英语听力计算机教室,每日英语听力电脑版|每日英语听力 v9.2.0 PC客户端
  20. LeedCode 717 1比特与2比特字符

热门文章

  1. Docker Java程序镜像制作
  2. 关于结构体的浅拷贝和深拷贝
  3. setpairint,int 的用法
  4. 使用变量的值作为JS对象的属性名,从而获取其对应的值
  5. 一次java线程死锁的定位
  6. MySQL分页查询中该避开的坑
  7. android 回退函数,android浏览器研究-回退和前进
  8. 2007级计算机技术专科毕业设计,2007级计算机科学与技术本科毕业设计选题
  9. datagridview 排序后 选择不变_排序算法之插入排序
  10. 燃气灶电气线路图及原理_电气安装造价如何入门,核心知识已为你打包