码迷,mamicode.com
首页 > 其他好文 > 详细

AsyncTask的前世今生

时间:2015-08-16 22:47:37      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:

 技术分享
     Callable与Runnable类似,差别在Callable具有返回值,共同点是两个都是执行体,一般都抽象为任务处理。
设计Future是对任务处理结果的生命周期维护行为,提供获取结果、取消、判断执行状态。Java现有的Thread Framework均基于Runnable,RunnableFuture提供了这样的抽象:可以借助Thread执行,并可维护执行结果。RunnableFuture中体现中设计了任务的载体(通过继承Runnable,可依托Thread Framework),任务的处理结果维护,而具体的任务则未定义,FutureTask便增加了该属性,它是一个完整的任务抽象:任务自身(Callable)、任务载体(Runnable)、任务结果维护(Future)。
     Executor的设计主要为了解决传统任务提交和任务处理耦合的问题,它将任务提交、任务处理解耦,便于任务调度策略的处理。
AbstractExecutorService对任务提交、执行解耦做了细化,提供了submit接口,并给caller反馈Future对象,便于caller获知result
Executor和AbstractExecutorService均未定义线程提交后该如何schedule、如何执行,这个可以有很多实现方法,ThreadPoolExecutor便是其中
比较主流的一种:线程池管理方式。
     具体的实现可参看jdk或android中libcore源码,此处不累赘,下面主要讨论Android中的异步线程类AsyncTask,它便是基于Java的Thread Framework做的封装,我们可以看下AsyncTask的类图(基于Android API 22):
     技术分享
        可以看到AsyncTask本质上是一个FutureTask+Executor, 提供了两个默认执行器:SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR,如下:
技术分享
        从Android 3.0 (API Level 13)之后,AsyncTask默认采用SERIAL_EXECUTOR, 即单线程执行策略,但是它并不是单独启动一个线程处理,其执行载体仍然是THREAD_POOL_EXECUTOR,只是控制为每次只执行一个任务,因此仍然可能会出现TASK Rejected的问题。
       AsyncTask的任务提交均在UI线程执行,其流程如下:
       技术分享
     可以看到任务的真正执行实体是FutureTask,它在executor的执行是异步的,具体实现可以参考线ThreadPoolExecutor执行
任务的流程,此处不赘述,mFuture的实现如下:
     技术分享
     doIngBackground由AsyncTask子类override实现,此处postResult是通过handler将消息传到UI线程的消息队列,
技术分享
此处getHandler()对应的是UI线程looper,handleMessage的处理就已经转到UI Thread了。
技术分享
技术分享
至此,AsyncTask从提交、执行、反馈结果的流程执行完毕,总结一下:
1.AsyncTask聚合了FutureTask和Executor,将Threading Framework的实现屏蔽在Framework层,APP侧只要傻傻地override
onPreExecute、doInbackground、onPostExecute即可,大大便利APP层对异步任务的使用需求。
2.按照谷歌官网说法,AsyncTask比较适合short time asynchronous task execution, 如果任务比较耗时,还是建议直接使用
Threading Framework提供的api,创建合适的executor。
3.默认的串行执行器并非单独开辟一个线程,仍以AsyncTask内置的线程池执行器为执行载体,因此仍然会存在被拒绝的可能性。
 
Ref:

AsyncTask的前世今生

标签:

原文地址:http://www.cnblogs.com/tonybright/p/4735099.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!