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. Luogu P3646 [APIO2015]巴厘岛的雕塑

    深夜写题解系列,话说这题暑假的时候就在LOJ上做掉了,然后今天看到Luogu上有就去交了一下,发现没写过题解,赶紧来补一下 说句题外话APIO2015的题目好水啊 首先考虑按位取或的过程,很显然要从二 ...

  2. 基于web公交查询系统----管理员公交站点管理页面实现

    主要用到内容:vue,coreui bootstrap框架,Ajax,springmvc搭建的接口,css之类的都是顺手拈来的简单的界面设计 网页代码: <!DOCTYPE html> & ...

  3. RocketMQ的顺序消费和事务消费

    一.三种消费 :1.普通消费 2. 顺序消费 3.事务消费 1.1  顺序消费:在网购的时候,我们需要下单,那么下单需要假如有三个顺序,第一.创建订单 ,第二:订单付款,第三:订单完成.也就是这个三个 ...

  4. layui 数据表格里面的html代码转义

    table.render({  elem: '#release_table'  ,url:'data_list'  ,where: {table: 'release'} //两步转义转义,先将原始数据 ...

  5. ThinkPHP框架获取上一条插入语句产生的id

    今天在fastAdmin框架想搞一个拖动进行排序的功能 遇到一个问题是权重的字段值一样的话拖动会出bug,所以想让权重字段(weigh)的值等于当前id的值, 搜索看到的方法如下 实际应用的地方,是写 ...

  6. IDEA创建xml文件

    今天在用IDEA写项目的时候发现,创建xml文件只能通过File手动输入去创建,但在我看的一个学习视频上可以直接创建xml文件,好奇之下研究了一下,作此篇,希望能对需要的朋友有所帮助. 废话就不多说了 ...

  7. 【机器学习】PCA

    目录 PCA 1. PCA最大可分性的思想 2. 基变换(线性变换) 3. 方差 4. 协方差 5. 协方差矩阵 6. 协方差矩阵对角化 7. PCA算法流程 8. PCA算法总结 PCA PCA 就 ...

  8. 2018-8-10-WPF-checkbox文字下掉

    原文:2018-8-10-WPF-checkbox文字下掉 title author date CreateTime categories WPF checkbox文字下掉 lindexi 2018- ...

  9. Enum.GetUnderlyingType(obj.GetType())

    Enum.GetUnderlyingType(obj.GetType())获取保存枚举值的数据类型:

  10. 搭建 Frp 来远程内网 Windows 和 Linux 机子

    魏刘宏 2019 年 5 月 19 日 一.使用一键脚本搭建服务端 Frp 这个内网穿透项目的官方地址为 https://github.com/fatedier/frp ,不过我们今天搭建服务端时不直 ...