大约Android 3.0后AsyncTask默认的单线程分析
在Android下了很大的后台操作在需要的情况下。通常用于AsyncTask这个类。比方说,网络负载形象。访问server接口。一般的情况是使用一个的一例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;
</pre><p></p><pre>
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
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;
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}
看看这个sDefaultExecutor与原来的THREAD_POOL_EXECUTOR线程池有什么 区别,sDefaultExecutor实际上是指向SerialExecutor的一个实例,从名字上看是一个顺序运行的executor;
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);
}
}
}
分析SerialExecutor,当提交一个任务。运行一次execute(),向mTasks加入一个runnable。此时mActive为null。接着会运行scheduleNext(),将mActive指向刚刚加入的runbale,并提交到THREAD_POOL_EXECUTOR中运行,接着就线程池中就会运行以下这段代码。
try {
r.run();
} finally {
scheduleNext();
}
当asyncTask提交大量的任务时。会反复之前的流程。任务都加入至mTasks中了,提交第一个任务之后,mActive便不再为Null了,之后的任务假设要被运行就必需等到前一个任务run方法跑完,也就是try{ }语句块中的run(),前一个任务运行完后,才会调用finally
后面的scheduleNext()从mTasks中取出下一个任务来运行。
分析完上面的代码后,如今对于3.0以后AsyncTask默认情况下同一时候仅仅存在一个线程顺序运行的原理就了解清楚了;
假设想要提交的任务在能并行运行呢?这在网络图片显示中还是比較实用的;
AsyncTask也为我们提供了第二种启动方法
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,Params... params)
这里能够指定自己定义的executor,而不再用SerialExecutor,假设乐意的话当然也能够直接使用用原本的THREAD_POOL_EXECUTOR,这样就能够保证多个任务并行运行了。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
大约Android 3.0后AsyncTask默认的单线程分析的更多相关文章
- IIS6(Win2003) 使用.net 4.0 后,默认文档失效解决方案。
IIS6(Win2003) 使用.net framework 4.0 后,默认文档失效解决方案. 用.net framework 4.0 开发的WEB项目,但放到iis6 中无法使用默认文档,状况如下 ...
- android 4.0后不允许屏蔽掉home键
屏蔽home键的方法 // 屏蔽掉Home键 public void onAttachedToWindow() { this.getWindow().setType(WindowManager.Lay ...
- Android Studio安装后配置默认新工程目录以及.gradle,.android,.m2和system,config目录
关于在哪里设置:以下所有设置都是在没有打开工程的前提下设置的, Configure > Settings 如图: 不要使用 Configure > Project Defaults> ...
- 转 Android 4.0后,自定义Title报错 You cannot combine custom titles with other title feature
自定义Titlebar时为了避免冲突 需要修改:AndroidManifest.xml android:theme="@style/mystyle" styles.xml文件中 ...
- Android 6.0 M userdebug版本执行adb remount失败
[FAQ18076]Android 6.0 M版本默认会打开system verified boot,即在userdebug和user版本会把system映射到dm-0设备,然后再挂载.挂载前会检查s ...
- Android 5.0之后屏幕截图的方法
截图的几种方法 Android获取屏幕截图主要有以下三种方法 1.通过view.getDrawingCache()获取指定View的绘制缓存来实现截屏. 这种方式Android 5.0之前也可以,且不 ...
- Android权限管理之RxPermission解决Android 6.0 适配问题
前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...
- Android 5.0之前屏幕截图的方法
截图的几种方法 Android获取屏幕截图主要有以下三种方法 1.通过view.getDrawingCache()获取指定View的绘制缓存来实现截屏. 这种方式Android 5.0之前也可以,且不 ...
- Android 9.0适配遇到的问题1
文章同步自javaexception 本周在适配Android 9.0,过程中碰到了小问题 问题1: SSL handshake timed out 解决办法: Android 9.0 开始,默认不允 ...
随机推荐
- 解决一bug的流程复盘
听同事说有一个功能不好使了,当时有事,过了一段时间来看看这个bug 解决问题时,看的是老的日志,根据老日志看来看去没有发现问题,觉得很困惑 然后手动执行了一下,发现问题没有重现.与另一个团队的同事沟通 ...
- Behavioral模式之Observer模式
1.意图 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都得到通知并被自己主动更新. 2.别名 依赖(dependents).公布-订阅(Publish-Subscr ...
- NSIS:禁止选择安装路径和编辑安装目录
原文 NSIS:禁止选择安装路径和编辑安装目录 如果你想在安装包中禁止用户选择安装路径和编辑安装目录,有两种方式. 第一种:注释或删除安装目录选择页面 1 ;!insertmacro MUI_PA ...
- 采用Visual Stuidio 2010 创建网站栏
采用Visual Stuidio 2010 创建网站栏 Visual Stuidio 2010 该项目模板使创建网站栏/内容类型和列表变得非常方便. 1. 管理员身份打开Visual Stuidio ...
- (大数据工程师学习路径)第四步 SQL基础课程----select详解
准备 在正式开始本内容之前,需要先从github下载相关代码,搭建好一个名为mysql_shiyan的数据库(有三张表:department,employee,project),并向其中插入数据. 具 ...
- C# Windows Schedule task此次收购task下一步执行时间
最近进行了一次需求和Windows Schedule task相关职能,通过schedule,计算下一次运行task时间. 它用于由第三方DLL实现,以下网站,以下载来自: http://tasksc ...
- JAVA8,SPRING,ANGULARJS对项目
java8+spring+angularjs 项目应用 最近有写一个电子订单商务网站,使用JAVA8,SPRING,ANGULARJS对项目使用的技术和大家分享. 第一次写博客,哪有不对需要改正的请联 ...
- Android研究之游戏开发处理按键的响应
1.onKeyDown 方法 onKeyDown 方法是KeyEvent.Callback 接口中的一个抽象方法,重写onKeyDown 方法能够监听到按键被按下的事件,我们先看看onKeyDown方 ...
- MessageDigest简要
本文博客原 參考文章:http://blog.sina.com.cn/s/blog_4f36423201000c1e.html 一.概述 java.security.MessageDigest类用于为 ...
- 变焦控制ZoomControls
在安卓的webview中有这个点击放大缩小button,当时就在想如何实现那种效果,弄一个两个图标的ImageButton.但感觉又有些麻烦,昨天看疯狂安卓书.无意中发现另一个 ZoomButtons ...