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线程就毫无压力了。

最新文章

  1. ERROR ITMS-90167: &quot;No .app bundles found in the package&quot;错误
  2. svn: 期望文件系统格式在“1”到“4”之间;发现格式“6”
  3. CE取系统时间值
  4. 15款精美的 WordPress 电子商务网站模板
  5. 夺命雷公狗---DEDECMS----16dedecms取出首页今日更新
  6. using System.Threading.Tasks;
  7. jsp空页面导致的jvm heap溢出
  8. mysql B+树 Cardinality MRR
  9. 基于jenkins搭建一个持续集成服务器
  10. java中matches的用法
  11. spring实例化bean三种方式
  12. 限定 edittext 的 输入内容
  13. Python捕捉系统信号
  14. Python:黑板课爬虫闯关第四关
  15. Mongo 用户管理
  16. sbadmin表单事件
  17. 【转】Git 代码行统计命令集
  18. 通过inotify实现反调试
  19. Linux上web服务器搭建
  20. Learning by doing——百日“扇贝打卡” 历程&amp;展望

热门文章

  1. 用Node.js给邮箱发送邮件
  2. PyCharm工具配置和快捷键使用
  3. QList去掉重复项 .toSet()报错???
  4. netstat查看端口状态
  5. 【前端知识体系-JS相关】虚拟DOM和Diff算法
  6. win10怎么打开服务界面?
  7. 记录一个 C# 导出 Excel 的坑
  8. Mongodb的常用语句
  9. linux部署java命令
  10. NRF24L01双向无线通信