AsyncTask版本的差异
来源:互联网 发布:移动3g卡能用4g网络 编辑:程序博客网 时间:2024/04/29 15:25
今天我们来说说AsyncTask版本之间的差异,我们现在使用AsyncTask通常会使用如下方式:
class DownloadTask extends AsyncTask<Void,Integer,String>{ @Override protected String doInBackground(Void... params) { return null; } }
然后我们怎么执行任务呢:
new DownloadTask().execute();
今天我们通过源码来看看AsyncTasik版本之间的差异,我们点进去execute()这个方法:
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
我们可以看到execute()这个方法实际上是调用了executeOnExecutor(sDefaultExecutor, params)这个方法,这个方法接收两个参数,我们重点看第一个参数,这是一个Executor对象,我们看看它是在哪定义的
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
我们看到sDefaultExecutor 的值是一个常量,然后我们继续看这个常量是什么
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
这个常量是一个SerialExecutor对象,我们点进去这个类:
private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } }
重点看scheduleNext这个方法,里面有个THREAD_POOL_EXECUTOR对象,这是什么,我们继续找
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
可以看到这里使用了线程池,其中常量定义如下:
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE = 1;
这是3.0之后的AsyncTask的源代码,每次当一个任务执行完毕后,下一个任务才会得到执行,SerialExecutor模仿的是单一线程池的效果,如果我们快速地启动了很多任务,同一时刻只会有一个线程正在执行,其余的均处于等待状态。
但是之前的代码不是这样的,在Android 3.0之前是并没有SerialExecutor这个类的,那个时候是直接在AsyncTask中构建了一个sExecutor常量,并对线程池总大小,同一时刻能够运行的线程数做了规定
private static final int CORE_POOL_SIZE = 5; private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 10; …… private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
可以看到,这里规定同一时刻能够运行的线程数为5个,线程池总大小为128。也就是说当我们启动了10个任务时,只有5个任务能够立刻执行,另外的5个任务则需要等待,当有一个任务执行完毕后,第6个任务才会启动,以此类推。而线程池中最大能存放的线程数是128个,当我们尝试去添加第129个任务时,程序就会崩溃。
因此在3.0版本中AsyncTask的改动还是挺大的,在3.0之前的AsyncTask可以同时有5个任务在执行,而3.0之后的AsyncTask同时只能有1个任务在执行。为什么升级之后可以同时执行的任务数反而变少了呢?这是因为更新后的AsyncTask已变得更加灵活,如果不想使用默认的线程池,还可以自由地进行配置。比如使用如下的代码来启动任务:
Executor exec = new ThreadPoolExecutor(15, 200, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); new DownloadTask().executeOnExecutor(exec);
这样就可以使用我们自定义的一个Executor来执行任务,而不是使用SerialExecutor。上述代码的效果允许在同一时刻有15个任务正在执行,并且最多能够存储200个任务。
下面对AsyncTask进行一下总结:
- AsyncTask版本的差异
- AsyncTask的版本差异及其与Thread的使用场景
- Android实战技巧:多线程AsyncTask(版本不同,有点差异)
- Android实战技巧:多线程AsyncTask(版本不同,有点差异)
- Android实战技巧:多线程AsyncTask(版本不同,有点差异)
- extjs版本差异带来的语法差异
- Windows7的版本差异比较
- IAR版本差异的问题
- AsyncTask 各版本的不同
- WinDbg不同版本间的主要差异
- Sql Server2000版本差异产生的问题
- 各个Javascript引擎及版本的差异
- web.xml版本差异的问题
- android系统版本间的差异
- mysql各个主要版本之间的差异.
- ListView刷新的版本间差异
- substring 的变异--jdk版本差异
- Android user 与 eng 版本的差异
- GeekBand学习笔记:C++三大函数:拷贝构造、拷贝赋值、析构函数
- oracle模糊查询语句使用示例
- Spring 3整合Quartz 2实现定时任务三:动态暂停 恢复 修改和删除任务
- Spring 4.2.4.RELEASE MVC 学习笔记 - 6.1 - (咋个办呢 zgbn)
- wowza流媒体服务器最详细教程-wowza安装配置及优化
- AsyncTask版本的差异
- 汇编学习笔记(一)
- Ionic模态化窗口使用
- Android Studio上非常棒的插件
- Java scripte 校验身份证号码的有效性
- hello world to php( mac 配置 xmapp virtual host)
- Spring 整合Quartz 2实现定时任务四:细化调整及一些已知的问题
- 4.5.2.3 android-Ultra-Pull-To-Refresh使用教程集锦
- Android6.0 应用调试