Android开发中执行耗时操作并更新UI时,通常有三种方式:
1.直接调用runOnUiThread(new Runnable(){}),使用简单,但不能在Activity之外的环境使用,如View、Dialog等;
2.使用AsyncTask实现,通过onPreExecute()、doInBackground()、onPostExecute三个方法能方便的分开UI操作和耗时操作,避免UI线程阻塞,并且支持参数传递;
3.Handler结合Message实现,比较重量级,但还需要用到Looper等,而且Message封装的Bundle对象不能太大,否则会抛异常。
几种方式各有利弊,实际开发中应根据需要选取合适方式,如Activity中可采用方法1和3,其他场合可使用方式2。

公司的项目中最近经常出现数据加载不出来的问题,而且切换网络环境后,出现概率会变小,因此起初一直以为是HTTP请求模块的问题,将Socket的timeout设置为一分钟后,一开始确实没有再重现,但过了几天问题又重现了,于是通过转包并请后台API相关开发人员查看日志分析,发现请求根本都没发出去!这样进一步确定是APP这边的问题,但究竟出在哪里一片茫然。
今天进行代码重构,涉及到AsyncTask这部分代码,通过logcat竟然发现onPreExecute()方法执行之后迟迟不进入doInBackground()方法!看来这就是问题所在。前一个task执行后,后一个task一直无法从pending状态进入running状态,说明线程阻塞了。
仍然是从StackOverflow上找到了启示:
API 11以前的AsyncTask线程池大小默认size为1,所以很容易阻塞,而之后的API提供了一个新方法executeOnExecutor(Executor exec, Params… params),第一个参数有两个常量值可选:
1.SERIAL_EXECUTOR: 相当于之前的execute()方法,多个task串行,可能阻塞;
2.THREAD_POOL_EXECUTOR: 线程池,默认size为5;
这样我们可通过判断API Level调用不同的方法:

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
void startMyTask(AsyncTask asyncTask) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
}else{
asyncTask.execute(params);
}
}

但是如果需要同时执行更多task(当然这个要尽量避免),仅仅使用AsyncTask也搞不定了,还需要通过BlockingQueue和ThreadPoolExecutor定义自己的线程池:

int corePoolSize = 60;
int maximumPoolSize = 80;
int keepAliveTime = 10;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(maximumPoolSize);
Executor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue);
asyncTask.executeOnExecutor(threadPoolExecutor);

这样同时跑多个task线程就毫无压力了。

解决Android中AsyncTask的多线程阻塞问题的更多相关文章

  1. Android中AsyncTask异步

    今天我们学习了 AsyncTack, 这是一个异步任务. 那么这个异步任务可以干什么呢? 因为只有UI线程,即主线程可以对控件进行更新操作.好处是保证UI稳定性,避免多线程对UI同时操作. 同时要把耗 ...

  2. Android中AsyncTask使用具体解释

    在Android中我们能够通过Thread+Handler实现多线程通信.一种经典的使用场景是:在新线程中进行耗时操作.当任务完毕后通过Handler向主线程发送Message.这样主线程的Handl ...

  3. 解决Android中No resource found that matches android:TextAppearance.Material.Widget.Button.Inverse问题

    解决Android中No resource found that matches android:TextAppearance.Material.Widget.Button.Inverse问题http ...

  4. Android中AsyncTask的使用 (包含文件的下载与存储)

    今天看到大神写的相关详解Android中AsyncTask的使用,真的很是佩服,下面我将学习到的AsynTask知识运用到项目中,其中也涉及一些文件的下载与存储到本地 啥都不说了,直接上代码,我将对其 ...

  5. Android中AsyncTask的简单用法 .

    在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行.在单线程模型中始终要记住两条法则: 1. 不要阻塞UI线程 2. 确保只 ...

  6. 并发编程之Android中AsyncTask使用详解(四)

    更多Android高级架构进阶视频免费学习请点击:[https://space.bilibili.com/474380680] 在Android中我们可以通过Thread+Handler实现多线程通信 ...

  7. 详解Android中AsyncTask的使用

    在Android中实现异步任务机制有两种方式,Handler和AsyncTask. Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更 ...

  8. 具体解释Android中AsyncTask的使用

    在Android中实现异步任务机制有两种方式,Handler和AsyncTask. Handler模式须要为每个任务创建一个新的线程,任务完毕后通过Handler实例向UI线程发送消息,完毕界面的更新 ...

  9. Android中AsyncTask的使用

    原文 https://blog.csdn.net/liuhe688/article/details/6532519 在Android中实现异步任务机制有两种方式,Handler和AsyncTask. ...

随机推荐

  1. luoguP4248 [AHOI2013]差异

    题意 考虑式子前面那段其实是\((n-1)*\frac{n*(n+1)}{2}\),因为每个后缀出现了\(n-1\)次,后缀总长为\(\frac{n*(n+1)}{2}\). 现在考虑后面怎么求: \ ...

  2. 有史以来Mysql面试题大全详解?

    1.MySQL的复制原理以及流程 根柢原理流程,3个线程以及之间的相关: 主:binlog线程——记载下悉数改动了数据库数据的语句,放进master上的binlog中:​ 从:io线程——在运用sta ...

  3. 奇安信集团笔试题:二叉树的最近公共祖先(leetcode236),杀死进程(leetcode582)

    1. 二叉树最近公共祖先     奇安信集团 2020校招 服务端开发-应用开发方向在线考试 编程题|20分2/2 寻祖问宗 时间限制:C/C++语言 1000MS:其他语言 3000MS 内存限制: ...

  4. python-10-列表、元组嵌套

    前言 元组.列表前面章节有讲解实例,本节内容是列表.元组的多嵌套. 一.列表嵌套 1.列表嵌套操作1 # 列表的嵌套 li = ['xiaolong', '小林', ['小龙', 'xiaol'], ...

  5. torch_10_stackGAN-V2

    核心要点 StackGAN旨在生成高分辨率的真实图片. stackGAN-v1架构包含两个阶段:用于文本到图像的合成,阶段1GAN根据给定的文本描述绘制对象的形状和颜色,生成低分辨率图像.阶段2将阶段 ...

  6. List集合分组实现教程

    封装一个方法,用一个Map来实现,这里是根据bean类的seq字段进行拆分的,分成好几个list private LinkedHashMap<String,List<HandleInfo& ...

  7. Mysql 常用数据类型 占用字节数 [转]

    数据类型是定义列中可以存储什么数据以及该数据实际怎么存储的基本规则.Mysql的常用数据类型主要有: 串数据类型:最常用的数据类型,有两种基本的串类型:分别为定长串和不定长串.定长串结束长度固定的字符 ...

  8. Kafka关键参数设置

    生产环境中使用Kafka,参数调优非常重要,而Kafka参数众多,我们的java的Configuration代码中,经常设置的参数如下: Properties props = new Properti ...

  9. 短的 Guid 帮助类

    直接贴代码了: /// <summary> /// 短的 Guid 帮助类 /// </summary> public class ShortGuidHelper { #reg ...

  10. Django学习笔记(11)——开发图书管理页面

    一,项目题目: 开发图书管理页面 该项目主要练习Django对多个数据库进行增删改查的操作. 二,项目需求: 基础需求:75% 1. 列出图书列表.出版社列表.作者列表 2. 点击作者,会列出其出版的 ...