为什么Android的AsyncTask不适合执行长时间操作的任务

Android API中有提到,AsyncTask非常适合短时间异步操作。如果要执行长时间操作,最好使用线程池Executor:

AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask. 

也许很多人会有疑问,这是为什么呢?后来我在stackoverflow上找到了一个比较好的回答

      提到了两个原因:

  • AsyncTask的生命周期没有跟Activity的生命周期同步
  • 容易内存泄露

AsyncTask和Activity的生命周期

      如果你在一个Activity中创建了一个AsyncTask,你旋转了屏幕,这个Activity将会被销毁并且会重新创建一个新的实例。但是AsyncTask没有销毁,它将会继续执行直到完成。当它执行完成后,它实际上是更新了上一个已经不存在的Activity,如果你原本想在onPostExecute()中更新UI的话,这时的AsyncTask将不会更新新的Activity,并且这个操作会引发一个异常:java.lang.IllegalArgumentException。
      如果你是想要在onPostExecute()中关闭一个dialog,则会发生:java.lang.IllegalArgumentException: View not attached to window manager(前提是你忘记在Activity的onStop()中忘记dismiss)。不仅如此,还会在show()的调用出抛出一个lead window的异常:
[java]  view plain copy
  1. Activity com.xxx.XXXActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{5350b3f4 V.E..... R....... 0,0-729,192} that was originally added here  
但那个回答中提到,如果你使用了findVIewById来提取Activity中的view也会发生异常,但经过测试没发现。

内存泄露问题

      在Activity中作为内部类创建AsyncTask很方便。因为AsyncTask在执行完成或者执行中需要使用Activity中的view,因为内部类可以直接访问外部类的域(也就是变量)。然而这意味着内部类会持有外部类的一个引用。
      当长时间运行时,因为AsyncTask持有Activity的引用,所以即使当该Activity不再显示时Android也无法释放其占用的资源。
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值