转自:http://blog.csdn.net/snow4dev/article/details/8809897

当AsyncTask被介绍到Android中时,它被贴上“无忧线程”的标签。其目标是让与UI线程交互的后台线程变得更容易。从这一点上讲它是成功的,但并非绝对安全————有很多AsyncTask无法应对的情况。如果不小心处理,不会考虑到AsyncTask出错的情况,很容易盲目使用AsyncTask。下面是一些未充分理解AsyncTask会遇到的问题:

AsyncTask与(屏幕)旋转

AsyncTask的起初目标是为了简化与UI线程进行交互的后台线程的实现。因此多数使用场景是用一个AsyncTask去运行一个耗时的操作,完成之后去更新UI部分(在AsyncTask.onPostExecute()中实现)。

当你旋转屏幕,你会发现这种做法是相当...。当一个App旋转时,整个Activity会被销毁和重建。当Activity重启时,AsyncTask中对该Activity的引用是无效的,因此onPostExecute()就不会起作用。如果使用AsyncTask作为Activity的内部类,AsyncTask会隐式引用了当前Activity,就会出现上述情况,这会使你非常疑惑。

这个问题的通常做法是对AsyncTask持有一个引用,在配置更改,随着Activity重启更新目标Activity。有多种方式可以实现,要么使用一个全局性的持有者(如Application对象),或者通过Activity.onRetainNonConfigurationInstance().传递一个对象。对于基于Fragment的系统,可以使用保留的Fragment(通过Fragment.setRetainedInstance(true)获取)去存储正在运行的AsyncTasks。

AsyncTasks与生命周期

与上面的提到一样:认为生成AsyncTask的Activity终止了,AsyncTask也会终止,这其实是一个误解。它会以它自有的方式继续运行,即使你退出了整个应用程序。AsyncTask提前结束的唯一方法是通过调用AsyncTask.cancel()进行取消。

这表明你必须亲自管理 AsyncTask的取消操作;否则,由于不必要的后台线程会导致app阻塞的风险,或者内存泄露。当不再需要一个AsyncTask时,一定要取消它,防止在app执行期间引起任何问题。

取消AsyncTasks

假设你有一个运行与AsyncTask中的搜索查询。在AsyncTask运行时,用户也许会改变搜索参数,因此你要调用AsyncTask.cancel(),并且为接下来的查询启动一个新的AsyncTask。这似乎合乎逻辑...检查日志后会发现所有的AsyncTask都会完整执行,不论你是否调用了cancel()方法。

传递mayInterruptIfRunning(cancel()方法的参数名)为true都会发生这种情况—————回事?

出现这种情况是因为误解了AsyncTask.cancel()的实际执行效果。AsyncTask不会不考虑结果而直接结束一个线程。调用cancel()其实是给AsyncTask设置一个"canceled"状态。这取决于你去检查AsyncTask是否已经取消,之后决定是否终止你的操作。对于mayInterruptIfRunning——它所作的只是向运行中的线程发出interrupt()调用。在这种情况下,你的线程是不可中断的,也就不会终止该线程。

多数情况下,有两个简单的方法可供选择:在长期运行的操作中定期检查AsyncTask.isCancelled()的调用;或者使线程中断。不论哪种方法,当你调用AsyncTask.cancelled()时,这些方法应该阻止你的操作继续运行。

这个建议并非总是有效————要是调用一个长期运行切不可中断的方法(如 BitmapFactory.decodeStream())会怎么样呢?成功的案例是创建一个引起异常抛出的场景(过早地关闭BitmapFactory使用的流)。这说明cancel()调用并不能解决这个问题————需要外部介入。

在当前AsyncTasks中的限制

我不提倡在后台启动数百个线程;并且,在可启动AsyncTasks的数量上做出限制将毫无用处。最新版的AsyncTask限制使用128个并发线程,另外还有10个在阻塞队列中。因此在队列任务完成之前,如果队列中的task多于138个就会引起app崩溃。使用AsyncTasks从网络加载位图(Bitmap)就会出现这样的问题。

如果想突破这些限制,应该重新思考对后台线程调用的设计。一个可选方案:对tasks设置一个更智能化的队列,这样不必一次性全部启动它们。要是情况紧急,可以拷贝AsyncTask的副本并在代码中调整线程池的大小。

AsyncTask隐藏的陷阱的更多相关文章

  1. C++基于范围循环(range-based for loop)的陷阱

    C++的基于范围的循环是C++11出现的新特性,很方便,一定程度上替代了使用迭代器的for循环用法.不过基于范围的for循环有一个隐藏的陷阱,如果不注意可能会出现严重的内存错误. 举例说明 看下面这个 ...

  2. java生产环境增量发版陷阱【原】

    前言 在生产环境,我们为了降低发版风险,一般都只做增量发布,不做全量发布. 除非项目只有一到两人开发,对时间线和代码脉络结构一清二楚,才可全量发布. 然而增量发布也是有一定隐藏陷阱在里面的,以下就是笔 ...

  3. 深入理解脚本化CSS系列第五篇——动态样式

    前面的话 很多时候,DOM操作比较简单明了,因此用javascript生成那些通常原本是HTML代码生成的内容并不麻烦.但由于浏览器充斥着隐藏的陷阱和不兼容问题,处理DOM中的某些部分时要复杂一些,比 ...

  4. 滴滴与Uber的竞争分析

    滴滴与Uber的竞争分析 随着互联网时代的到来,智能手机的普及,互联网不再是一个完全虚拟的东西,它开始慢慢地融入到我们的生活中来.这些年我们可以明显地感受到我们的生活方式在一天天发生着变化,我们也逐渐 ...

  5. JavaScript 闯关记

    DOM(文档对象模型)是针对 HTML 和 XML 文档的一个 API.DOM 描绘了一个层次化的节点树,允许开发人员添加.移除和修改页面的某一部分. 节点层次 DOM 可以将任何 HTML 或 XM ...

  6. 【JavaScript】【译】编写高性能JavaScript

    英文链接:Writing Fast, Memory-Efficient JavaScript 很多JavaScript引擎,如Google的V8引擎(被Chrome和Node所用),是专门为需要快速执 ...

  7. 编写高性能JavaScript【转】

    英文链接:Writing Fast, Memory-Efficient JavaScript 很多JavaScript引擎,如Google的V8引擎(被Chrome和Node所用),是专门为需要快速执 ...

  8. 《JavaScript 闯关记》之 DOM(下)

    Element 类型 除了 Document 类型之外,Element 类型就要算是 Web 编程中最常用的类型了.Element 类型用于表现 XML 或 HTML 元素,提供了对元素标签名.子节点 ...

  9. NIO相关基础篇三

    转载请注明原创出处,谢谢! 说在前面 上篇NIO相关基础篇二,主要介绍了文件锁.以及比较关键的Selector,本篇继续NIO相关话题内容,主要谈谈一些Linux 网络 I/O模型.零拷贝等一些内容, ...

随机推荐

  1. LG5536 「XR-3」核心城市 树的直径

    问题描述 LG5536 题解 两次 \(\mathrm{dfs}\) 求树的直径. 然后找到树的直径的中点. 然后按照 子树中最深的点深度-自己深度 排序,贪心选取前 \(k\) 个. \(\math ...

  2. CF1005F Berland and the Shortest Paths 最短路树计数

    问题描述 LG-CF1005F 题解 由题面显然可得,所求即最短路树. 所以跑出最短路树,计数,输出方案即可. \(\mathrm{Code}\) #include<bits/stdc++.h& ...

  3. json去除value值的前后空格

    /** * @Title: JsonStrTrim * @author : jsw * @date : 2012-12-7 * @time : 上午09:19:18 * @Description: 传 ...

  4. 震惊!CCF改名为中国沙雕化学学会!!!

    震惊!中国沙雕计算机学会要改名中国沙雕化学学会??? Ak元素 据传,CCF,发现了一种新元素,元素符号暂命名为为Ak,中文名称暂未命名,据说是第250号元素. Ak 元素的发现 珂学家在一个叫洛谷的 ...

  5. centos7下安装php-memcached扩展

    -> https://blog.csdn.net/sinat_35861664/article/details/72831556 安装扩展进行编译时如果报错,则将 ./configure --w ...

  6. vue使用--saas的引入与使用

     什么是saas.scss? saas是一种动态样式语言,属于CSS预处理器,为CSS增加了一些编程特性,比如变量.嵌套.函数.继承.运算等等.开发人员可以像使用js等语言一样使用saas进行css的 ...

  7. JavaScript DOM 常用操作

    1.理解DOM: DOM(Document Object Model ,文档对象模型)一种独立于语言,用于操作xml,html文档的应用编程接口. 怎么说,我从两个角度理解: 对于JavaScript ...

  8. ICP&TPS:最近邻

    经过了一段时间的研bai究gei...终于可以偷得几天闲了. 这里来补个档. 无论是ICP还是TPS,缺乏锚点的前提下.你总是要通过找另一个曲面的最近的点来实现你的work beimat:点数*3,f ...

  9. HTML+css基础 css的几种形式 css选择器的两大特性

    3.外联样式 css选择器的两大特性 1.继承性:所有跟文本字体有关的属性都会被子元素继承.且权重是0000. 2.层叠性:就是解决选择器权重大小的一种能力,就是看那个选择器的权重大.谁的权重大听谁的 ...

  10. linq 大数据 sql 查询及分页优化

    前提: 需要nuget   PredicateLib   0.0.5: SqlServer  2008R2 (建议安装 64 位): .net 4.5 或以上: 当前电脑配置: I7 4核  3.6G ...