AsyncTask可谓是在Android中隐藏很深,曾经叱咤风云的功夫级人物。它的存在让网络和UI的通信变得异常简单和轻松。AsyncTask使用上的简单也得以让很多开发者青睐。一般情况下,AsyncTask会作为内部类在Activity或者Fragment中实现,例如:


相信很多朋友都是这么玩的。但是这样写会不会有问题呢?答案是肯定的。

首先,我们知道Java语言是一种强类型,强引用的语言。在一个类中创建内部类时,内部类会默认对外部类持有引用。可以简单的理解为,外部类作为了一个寄托者将内部类绑定在了自己身上。我们知道Activity或者Fragment是有生命周期存在的。并且AsyncTask多用于处理耗时操作(数据库,IO读写,网络请求等等。。)此时,就会出现一个严重的问题:在Activity或者Fragment生命周期结束后,由于AsyncTask的耗时任务尚未完成,导致Activity或者Fragment无法释放资源。即发生我们经常所听到的 “内存泄漏”。

有朋友可能不明白了,为什么会产生内存泄漏呢?

我们上面提到,由于内部类和外部类的绑定关系,并且AsyncTask的耗时操作导致外部类资源不能被及时GC。Java中默认的引用持有都是强引用类型。例如我们直接new出来的对象。为了避免这些问题,Java还为我们提供了软引用,弱引用,无引用持有等等一些工具。弱引用和软引用的作用几乎相同。都是在资源紧缺的情况下被得以回收。

所以,解决这个问题的关键之处就在于不要对外部类持有强引用,或者将内部类定义成static类型,让其与外部类拥有相同的生命周期。此时有朋友可能一脸懵逼,为啥定义成static就可以了。哈哈,你想哇,static静态的内部类属于外部类的静态成员,当外部类初始化时它才会被初始化,同样,当外部类被释放时,它也会被同时释放。也就是内部类与外部类同生共死。但是使用static类型的同样需要我们将在asyncTask中使用的变量也声明为static,数量少的情况下还是可以接受的,但是很多的static情况下,容易让内存吃紧,GC频繁。所以,合适的解决方案就是使用弱引用来改变内部类对外部类的引用关系。

即我们可以自定义一个Weak形式的AsyncTask,让其持有外部类的弱引用:


可以看到上面我们定义了一个WeakAsyncTask类继承自AsyncTask。在类中我们使用WeakRefrences来弱引用外部Context。所以,当外部类需要释放时,会立刻被GC所回收。避免了内存泄漏的问题。

使用方式很简单:

ok,本篇博客讲解了AsyncTask作为内部类导致内存泄漏以及以及如何解决该问题,相信大家也有了深刻认识。有问题的可以给我留言咯~

更多相关文章

  1. Android中使用SurfaceView的方法
  2. Android内存泄漏终极解决篇(下)
  3. android中handler使用WeakReference防止内存泄露
  4. Android(安卓)Service 通知Activity更新界面的方法研究|Service
  5. 在eclipse中使用ServiceManager
  6. Android(安卓)打包及引用 aar 文件的方法
  7. Android常见内存泄漏及优化总结
  8. Android(安卓)Studio下添加引用jar文件和so文件
  9. android 按钮点击事件

随机推荐

  1. Elasticsearch 崛起的那些事!
  2. 2020年12月-第01阶段-前端基础-认识WEB
  3. Vue技术栈开发学习之状态管理bus的使用
  4. Markdown编辑器优化意见征集
  5. 华为防火墙GRE ***配置
  6. 3-18(排序的完结)
  7. mybatis框架的插件机制
  8. 网易千万级日活背后的系统运维技术支撑
  9. CDN加速原理
  10. 从入门到放弃,50G编程视频免费送!