原文:http://www.2cto.com/kf/201411/348411.html
在Android里需要大量后台操作的情况下,经常会使用到AsyncTask这个类,比如说加载网络图片,访问服务器的接口,一般的使用情境就是实例化一个AsyncTask的对象mTask,复写AsyncTask的抽象方法doinBackgroud等等,最后执行task.execute(params),然后就可以在UI线程上方便的取得后台线程的执行结果;
AsyncTask执行中最终触发的是把任务交给线池THREAD_POOL_EXECUTOR来执行,提交的任务并行的在线程池中运行,但这些规则在3.0之后发生了变化,3.0之后提交的任务是串行运行的,执行完一个任务才执行下一个!
先看看3.0以前的代码;
- private static final int CORE_POOL_SIZE = 5;
- private static final int MAXIMUM_POOL_SIZE = 128;
- private static final int KEEP_ALIVE = 10;
- public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
3.0以前线程池里核心线程有5个,同时存在的线程数最大不能超过128个,线程池里的线程都是并行运行的;
但是在3.0之后,直接调用execute(params)触发的是sDefaultExecutor的execute(runnable)方法,而不是原来的THREAD_POOL_EXECUTOR
1
2
3
|
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 ;
|
1
2
3
|
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}
|
看看这个sDefaultExecutor与原来的THREAD_POOL_EXECUTOR线程池有什么 差别,sDefaultExecutor实际上是指向SerialExecutor的一个实例,从名字上看是一个顺序执行的executor;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
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);
}
}
}</runnable></runnable>
|
分析SerialExecutor,当提交一个任务,执行一次execute(),向mTasks添加一个runnable,此时mActive为null,接着会执行scheduleNext(),将mActive指向刚刚添加的runbale,并提交到THREAD_POOL_EXECUTOR中执行,接着就线程池中就会执行下面这段代码;
1
2
3
4
5
|
try {
r.run();
} finally {
scheduleNext();
}
|
当asyncTask提交大量的任务时,会重复之前的流程,任务都添加至mTasks中了,提交第一个任务之后,mActive便不再为Null了,之后的任务如果要被执行就必需等到前一个任务run方法跑完,也就是try{ }语句块中的run(),前一个任务执行完后,才会调用finally
后面的scheduleNext()从mTasks中取出下一个任务来执行;
分析完上面的代码后,现在对于3.0以后AsyncTask默认情况下同时只存在一个线程顺序执行的原理就了解清楚了;
如果想要提交的任务在能并行执行呢?这在网络图片显示中还是比较有用的;
AsyncTask也为我们提供了另外一种启动方法
1
|
public final AsyncTask<params, result= "" > executeOnExecutor(Executor exec,Params... params)</params,>
|
这里可以指定自定义的executor,而不再用SerialExecutor,如果乐意的话当然也可以直接使用用原本的THREAD_POOL_EXECUTOR,这样就可以保证多个任务并行执行了;
相关推荐
在Android中使用AsyncTask和Handler线程间交互的方式,详情参见博客:http://www.cnblogs.com/plokmju/p/android_AsyncTask.html和http://www.cnblogs.com/plokmju/p/android_Handler.html
Android中AsyncTask实现多线程计数,UI主线程运行,启动另一个线程计数并在UI主线程上显示.
AsyncTask 异步多线程加载Demo
AsyncTask_演示线程阻塞,对应我的博客《Android专题之AsyncTask(一)基本概念介绍》,有问题欢迎留言讨论。
主要介绍了android使用AsyncTask实现多线程下载实例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
12_Android 多线程AsyncTask详解
主要介绍了Android使用AsyncTask实现多线程下载的方法,以完整实例形式详细分析了Android使用AsyncTask实现多线程下载的功能代码,界面布局及权限控制的具体方法,需要的朋友可以参考下
Android Asynctask 先小试牛刀,了解一下各个方法执行过程,关注博客http://himici.com/
这是Pro Android学习系列中AsyncTask部分的例子源代码。相关学习笔记见:http://blog.csdn.net/flowingflying/article/details/6212512
Android开发之AsyncTask机制及使用细节例子源码 详见博客 http://www.cnblogs.com/samy/p/4217263.html
Android是单线程模型,耗时的操作必须放在非主线程中执行,对此,我们需要使用多线程/线程池或者AsyncTask等来完成异步加载任务。 博客地址:http://blog.csdn.net/chenzheng8975/article/details/53893666
AsyncTask的用法
Android AsyncTask的简单Demo,对应Blog文章:http://blog.csdn.net/dolacmeng/article/details/50215519
Android AsyncTask用法和异步加载图片通过AsyncTask 从网络上异步加载一张图片
NULL 博文链接:https://sc-robin.iteye.com/blog/991380
主要介绍了Android中异步类AsyncTask用法,分析总结了Async Task类的功能、特点及相关的使用技巧与注意事项,需要的朋友可以参考下
android Handler Thread AsyncTask httpURLConnection学习的代码
NULL 博文链接:https://byandby.iteye.com/blog/825071