AsyncTask源码理解

本文解析了Android中AsyncTask的工作原理及其默认串行执行的特点,指出了常见的使用误区,并提供了如何实现并行任务的建议。

其实我项目中很少用到AsyncTask,以前简单的看过AsyncTask的源码,知道它维护了一个线程池,知道4.0之前超过5个线程好像就会出问题,也没做过多研究,也几乎没用在实际开发中。废话一堆,进入正题。

首先大致说一下AsyncTask的原理,当调用execute时,会用默认的处理器sDefaultExecutor去执行mFuture,mFuture是一个FutureTask,FutureTask里包含一个CallablemWorker,在mWorker的call方法中执行doInBackground,然后通过sHandler发送消息到主线程,执行相关结束更新UI的方法。

这里要非常注意的一个点是:sDefaultExecutor是一个SerialExecutor,何为SerialExecutor?它是一个AsyncTask的内部类,通过它的名字我们惊奇的发现这是一个按顺序一个一个任务执行的线程池。下面来看一下它的源码:scheduleNext方法只有第一次mActive为null才会直接被执行,否则不会执行。执行scheduleNext方法后,同步执行r.run();(。。。直接同步执行r.run 。。 很神奇),执行完r.run以后,会执行finally里的代码块,这里会接着执行scheduleNext,执行下一个任务。所以通过分析源码也可得知它默认是顺序执行的一个线程池。

这里一定要看清楚了,很多人用AsyncTask的时候,直接execute完事,岂不知你只是用异步线程去执行了一个任务而已,并不能并行执行很多任务。同时启动多个AsyncTask去execute时,其实相当于是同步执行的。。

那怎么才能异步去执行很多任务呢?用executeOnExecutor,自己传一个ThreadPoolExecutor,或者直接用AsyncTask的一个常量THREAD_POOL_EXECUTOR,这就是一个已经定义好的线程池执行者,直接传进去就好了。

还有一个我以前的认知误区,我以前一直觉得AsyncTask跟ThreadPool是差不多的概念,一个对象不断execute就行了,其实不是。AsyncTask跟Thread是差不多的概念,讲究每次都new一个,然后execute,就像Thread,每次都new一个,然后start。

还有一个要注意的就是,AsyncTask的execute方法在哪个线程执行,onPreExecute就会在哪个线程执行。AsyncTask第一次在哪个线程new的,sHandler就会是哪个线程的handler。所以为了保证AsyncTask的正常执行,务必要保证AsyncTask是在主线程中new的,并且execute方法也是在主线程中执行的。

总之感觉AsyncTask名字起的不好,既然你默认是顺序执行的,那名字应该体现出顺序执行的意思,而且有各种隐藏的坑,我个人大家不推荐使用。

有问题及时反馈,谢谢阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值