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

简介:
  从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的子类来实现的,注意,这个函数是在应用程序的子线程中执行的,它不可以操作应用程序的界面。




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966888,如需转载请自行联系原作者
目录
打赏
0
0
0
0
235
分享
相关文章
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
184 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
190 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
59 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
112 14
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
157 21
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
64 8
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
3月前
|
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
120 4
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等