博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入解析AsyncTask
阅读量:4595 次
发布时间:2019-06-09

本文共 4002 字,大约阅读时间需要 13 分钟。

Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。相对来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现。 AsyncTask的功能在不在这里介绍。

 

3.0之前一直以来都是以下面的方式执行AsyncTask任务:

new AsyncTask
() { @Override protected Void doInBackground(Void... params) { // 处理耗时操作 return null; } }.execute();

 

3.0以上的手机上执行AsyncTask都不会使用上面的方式执行了,3.0以上的AsyncTask默认是单线程执行了。

所以要适配不同版本的手机,应该使用下面的工具类执行AsyncTask任务:

 

public class CommonUtils {    public static 
void executeAsyncTask( AsyncTask
task, Params... params) { if (Build.VERSION.SDK_INT >= 11) { task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); } else { task.execute(params); } }}

 

用法示例:

 

CommonUtils.executeAsyncTask(new AsyncTask
() { @Override protected Void doInBackground(Void... params) { // 处理耗时操作 return null; } });

 

 

 在3.0之后 执行execute默认会调用sDefaultExecutor

public final AsyncTask
execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }

 

sDefaultExecutor是一功能类似单线程池。THREAD_POOL_EXECUTOR就是和之前一样的工作线程池

 

public static final Executor THREAD_POOL_EXECUTOR            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);    /**     * An {
@link Executor} that executes tasks one at a time in serial * order. This serialization is global to a particular process. */ public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; private static final InternalHandler sHandler = new InternalHandler(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

 

下面看看SerialExecutor

 

private static class SerialExecutor implements Executor {      final ArrayDeque
mTasks = new ArrayDeque
(); 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); } } }

可以看到,SerialExecutor是使用ArrayDeque这个队列来管理Runnable对象的,如果我们一次性启动了很多个任务,首先在第一次运行execute()方法的时候,会调用ArrayDeque的offer()方法将传入的Runnable对象添加到队列的尾部,然后判断mActive对象是不是等于null,第一次运行当然是等于null了,于是会调用scheduleNext()方法。在这个方法中会从队列的头部取值,并赋值给mActive对象,然后调用THREAD_POOL_EXECUTOR去执行取出的取出的Runnable对象。之后如何又有新的任务被执行,同样还会调用offer()方法将传入的Runnable添加到队列的尾部,但是再去给mActive对象做非空检查的时候就会发现mActive对象已经不再是null了,于是就不会再调用scheduleNext()方法。

 

那么后面添加的任务岂不是永远得不到处理了?当然不是,看一看offer()方法里传入的Runnable匿名类,这里使用了一个try finally代码块,并在finally中调用了scheduleNext()方法,保证无论发生什么情况,这个方法都会被调用。也就是说,每次当一个任务执行完毕后,下一个任务才会得到执行,SerialExecutor模仿的是单一线程池的效果,如果我们快速地启动了很多任务,同一时刻只会有一个线程正在执行,其余的均处于等待状态。

不过你可能还不知道,在Android 3.0之前是并没有SerialExecutor这个类的,那个时候是直接在AsyncTask中构建了一个sExecutor常量,并对线程池总大小,同一时刻能够运行的线程数做了规定,代码如下所示:

 

而3.0之后的AsyncTask默认同时只能有1个任务在执行。3.0为了增加不同的需求,增强扩展性,变得更加灵活。如果不想使用默认的线程池,还可以自由地进行配置。比如使用如下的代码来启动任务:

 

Executor exec = new ThreadPoolExecutor(15, 200, 10,          TimeUnit.SECONDS, new LinkedBlockingQueue
()); new DownloadTask().executeOnExecutor(exec);

这样就可以使用我们自定义的一个Executor来执行任务,而不是使用SerialExecutor。上述代码的效果允许在同一时刻有15个任务正在执行,并且最多能够存储200个任务。

好了,到这里我们就已经把关于AsyncTask的所有重要内容深入浅出地理解了一遍,相信在将来使用它的时候能够更加得心应手。

 

 

 

4.3系统

 

4.4系统的 

   CORE_POOL_SIZE变成了CPU个数+1。

   MAXIMUM_POOL_SIZE变成了2倍的CPU+1

原来的sPoolWorkQueue1在4.4之前队列都是大小为10,4.4之后队列大小是128

 

 

 

 

转载于:https://www.cnblogs.com/mingfeng002/p/3708141.html

你可能感兴趣的文章
How to Notify Command to evaluate in mvvmlight
查看>>
33. Search in Rotated Sorted Array
查看>>
461. Hamming Distance
查看>>
Python垃圾回收机制详解
查看>>
{面试题1: 赋值运算符函数}
查看>>
Node中没搞明白require和import,你会被坑的很惨
查看>>
Python 标识符
查看>>
Python mysql 创建连接
查看>>
企业化的性能测试简述---如何设计性能测试方案
查看>>
centos7 安装中文编码
查看>>
POJ - 3683 Priest John's Busiest Day
查看>>
正则表达式start(),end(),group()方法
查看>>
vuejs 学习旅程一
查看>>
javascript Date
查看>>
linux常用命令2
查看>>
狼图腾
查看>>
13、对象与类
查看>>
Sublime Text3 个人使用心得
查看>>
jquery 编程的最佳实践
查看>>
MeetMe
查看>>