【转】坑爹的AsyncTask之根本停不下来
原文网址:http://www.jianshu.com/p/0c6f4b6ed558
上篇《坑爹的AsyncTask之内存泄露》已经简单的探讨过线程使用不当会造成内存泄露的问题,在Activity中如果一个线程超出了Activity的生命周期是极有可能发生内存泄露的,那简单来说我们不让线程的生命周期长于Activity就能从根本上解决这个问题。我们今天探讨的主题就是如何让一个Run起来的线程去stop。
听起来有点不可思议,因为JAVA语言中并没有提供相应的API来停止一个正在运行的线程,再来看看我们Android中的“无忧线程”AsyncTask,源码看下来找到一个cancel()方法,看起来似乎是用来cancel当前线程的,写个demo测试下究竟,结果发现这货根本不靠谱。不可能啊,难道Android会提供不靠谱的API给开发者用嘛,回头再来看看cancel()方法的API说明
* <p>Calling this method will result in {@link #onCancelled(Object)} being
* invoked on the UI thread after {@link #doInBackground(Object[])}
* returns. Calling this method guarantees that {@link #onPostExecute(Object)}
* is never invoked. After invoking this method, you should check the
* value returned by {@link #isCancelled()} periodically from
* {@link #doInBackground(Object[])} to finish the task as early as
* possible.</p >
这段注释大概是说,如果调用cancel()方法,它不会立即执行,只有当doInBackground()方法执行完有返回值之后,会在UI主线程调用cancel(),同时也会间接的调用iscancelled(), 并且返回true ,这个时候就不会再调onPostExecute(),然后在doInBackground()里定期检查iscancelled()方法的返回值,是否被cancel,如果return true,就尽快停止。从这段注释里我们似乎发现cancel()方法本身就不太靠谱,因为它的调用在doInBackground()之后执行,假如我就想在doInBackground()里停止当前线程是不是就没有办法了,不保险加不靠谱,我们通过cancel()方法终止线程的想法显然走不通。
但是这段注释似乎给了我们一些启示,可以通过定期检查返回值的方法来判断是否需要停止当前线程。我们要知道在java中,是没有提供相关API来停止一个正在运行中的线程,而Android的AsyncTask也是一样的。如果必须要停止一个线程,我们可以合理利用Java中的Exception,让这个线程在检查到自己需要被停止的时候抛出异常,然后线程就不会再继续执行了,那怎么操作呢,我们可以在这个线程中的耗时操作中设置一些flag,也就是AsyncTask的doInBackground方法中的某些关键步骤。然后在外层需要终止此线程的地方改变这个flag值,线程中的耗时代码一步步执行,当某一时刻发现flag的值变了,throwException,线程就不会再继续执行了。为了保险起见,在外层我们还要捕获这个异常,进行相应处理。
看到这里你是否对这个粗暴的暂停办法留有疑问呢?这样做安全吗,如此粗暴的直接打断AsyncTask真的好么?关于安全问题,如果是在主线程上发生有未处理的异常,将直接导致整个进程终止,简单说就是要用程序fc。但是我们是在AsyncTask的doInBackground方法中打断线程的,doInBackground方法是子线程,子线程被发生异常后会自己死掉而不会引起其他问题,更不会影响到主线程,更何况我们为了更加安全还捕获了异常并做处理,所以这个办法还是安全的,亲测有效。
我们找到了停止Running线程的办法,那么下次只要在Activity生命周期结束之前也结束掉线程的生命,就可以让你的应用程序更加安全健壮了。
如有刊误,欢迎指正。
原文链接:http://www.jianshu.com/p/0c6f4b6ed558
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
【转】坑爹的AsyncTask之根本停不下来的更多相关文章
- Android(java)学习笔记149:Android线程形态之 AsyncTask (异步任务)
1. AsyncTask和Handler的优缺点比较: 1)AsyncTask实现的原理和适用的优缺点 AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTa ...
- Android(java)学习笔记92:Android线程形态之 AsyncTask (异步任务)
1. AsyncTask和Handler的优缺点比较: 1)AsyncTask实现的原理和适用的优缺点 AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTa ...
- Elasticsearch 的坑爹事——记录一次mapping field修改过程
Elasticsearch 的坑爹事 本文记录一次Elasticsearch mapping field修改过程 团队使用Elasticsearch做日志的分类检索分析服务,使用了类似如下的_mapp ...
- app里使用163邮箱发送邮件,被163认为是垃圾邮件的坑爹经历!_ !
最近有个项目,要发邮件给用户设定的邮箱报警,然后就用了163邮箱,代码是网上借来的^^,如下: package com.smartdoorbell.util; import android.os.As ...
- Service和Thread的关系及如何启用Service,如何停用Service
Service和Thread的关系: 不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会 ...
- AsyncTask delay延迟执行 或者顺序执行 问题
惯用AsyncTask的朋友可能会发现AsyncTask的坑: Android executes AsyncTask tasks before Android 1.6 and again as of ...
- Android学习笔记:进度条ProgressBar的使用以及与AsyncTask的配合使用
ProgressBar时android用于显示进度的组件.当执行一个比较耗时的操作(如io操作.网络操作等),为了避免界面没有变化让用户体验降低,提供一个进度条可以让用户知道程序还在运行. 一.Pro ...
- (转)Elasticsearch 的坑爹事——记录一次mapping field修改过程
Elasticsearch 的坑爹事 本文记录一次Elasticsearch mapping field修改过程 团队使用Elasticsearch做日志的分类检索分析服务,使用了类似如下的_mapp ...
- 坑爹的Adprep32.exe
今天看书的时候,看到用ADSI设置Universal Group Membership Caching,就想到用.Net Framework来实现,找了半天,才找到System.directoryse ...
随机推荐
- buf.readInt32LE函数详解
offset {Number} 0 noAssert {Boolean} 默认:false 返回:{Number} 从该 Buffer 指定的带有特定尾数格式(readInt32BE() 返回一个较大 ...
- 我和CSDN的那些事
作者:朱金灿 来源:http://blog.csdn.net/clever101 前些日子收到这样一个邀请: CSDN的工作人员还来电给我确认是否能参加.开始我有点犹豫,毕竟是在工作日的晚上,毕竟离我 ...
- Unity引擎GUI之Button
UGUI Button,可以说是真正的使用最广泛.功能最全面.几乎涵盖任何模块无所不用无所不能的组件,掌握了它的灵巧使用,你就几乎掌握了大半个UGUI! 一.Button组件: Interactabl ...
- 启动Mysql时,提示error 2002 的解决办法
故障描述 启动时提示ERROR 2002(HY000) 启动服务时,提示the server quit without updating PID file. 解决方法一: 1.由于mysql是卸载后重 ...
- 【Linux】tmpfs简介及增加方式
一. 什么是tmpfs? tmpfs是一种基于内存的文件系统,它和虚拟磁盘ramdisk比较类似,但不完全相同,和ramdisk一样,tmpfs可以使用RAM,但它也可以使用swap分区来存储.而且传 ...
- Verification之PSL之use
1 Where can PSL be used? • Documentation – Requirements – RTL Designs • Controllers – Memories, FIFO ...
- ROS和OpenCV的对接cv_bridge
做一个诚实的ROS教程搬运工............................. 官网链接:http://wiki.ros.org/cv_bridge 一.Package Summary Rel ...
- 身份认证防止重放攻击的challenge-response方法
或者叫询问-应答机制. 基于挑战/应答(Challenge/Response)方式的身份认证系统就是每次认证时认证服务器端都给客户端发送一个不同的"挑战"字串,客户端程序收到这个& ...
- HTTP协议探索之Cache-Control
缓存的存与用的控制 Cache-Control指定了请求和响应遵循的缓存机制.好的缓存机制可以减少对网络带宽的占用,可以提高访问速度,提高用户的体验,还可以减轻服务器的负担. Cache-Contro ...
- eas更改用户组织范围和业务组织范围
表: T_PM_OrgRangeIncludeSubOrg 10 20 30 分别代表 业务组织 行政组织 以及管辖组织.查行政组织,