AsynTask版本兼容问题

AsynTask本质其实是对线程池+Handler的封装,知道本质你就知道为什么能执行任务,为什么能更新UI了。

线程池这块使用了ThreadPoolExecutor


由于AsynTask在以往版本中被频繁的修改过,所以导致了不同版本使用的时候会出现崩溃,或者执行延迟很严重等等问题.

好那么带上疑问走进源码

这是API23源码略过一百多行注释。。。


上面标了两个线程池其实只有一个,第二个其实调的第一个。

 

上面常量那里可以看到,AsyncTask里面线程池是一个核心线程数为CPU + 1,最大线程数为CPU * 2 + 1,工作队列长度为128的线程池。

这里就有个问题,万一超过限制了呢?

线程会被阻塞,可能会延迟很久执行,或者直接抛异常,一种常见的情况就是快速滑动listview会在一瞬间产生很多请求,所以很多异步加载框架都会抛弃AsynTask自己去实现线程池和Handler。

 

注意到两个线程池上面的注释一个是parallel(并发),一个是serial order(顺序),然后API23默认使用顺序执行的也就是串行的SERIAL_EXECUTOR

 

再去看看SERIAL_EXECUTOR怎么是搞的


就是通过加一个队列,一个执行完再下一个,这样来做成了串行执行,而且做了synchronized处理


为什么现在的版本不是默认并行?

因为并行时,doInBackground会出现资源的同步问题,而开发者一般不会意识到需要在这里处理同步问题,干脆改成串行去避免问题,但是当你明确自己没有同步问题要处理的时候,可以使用executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)并行执行


AsyncTask修改历史

Android 1.5刚引入的时候,AsyncTask的execute是串行执行的

Android 1.6直到Android 2.3.2,又被修改为并行执行了,就是THREAD_POOL_EXECUTOR,因此在一个进程内,所有的AsyncTask都是并行执行的

Android 3.0以后,又改成了串行就是那个SERIAL_EXECUTOR3.0的改串行


可以从我这份API23的源码找到证明



这个构造方法,而sDefaultExecutor就是一开始看到的,已经赋值了SERIAL_EXECUTOR

 

以上是一些AsynTask的版本问题,就是因为被改来改去所有出现了版本引发问题,当使用到的时候留意一下这些问题,尽量少踩一些坑。


猜你喜欢

转载自blog.csdn.net/PK0071/article/details/51698886