最近用LeakCanary测了一下内存泄露, 好多内存泄露呀, 总结一下都有以下问题:
1. 使用volley-1.0.0造成的问题
网络访问的过程中需要给请求一个callback, 这个callback匿名内部类, 默认会持有外部类的一个引用, 这就导致Activity无法被释放
解决方法: 替换成volley-1.1.0然后可以在Activity的onDestroy里面调用Request的cancel方法, 进而将Activity给Request的callback置空, 这样Request就不再持有Activity的引用了
2. 单例类的Context属性
单例类是和Application一起销毁的, 这就导致所有被单例类引用的Activity一直没法被JAVA虚拟机释放掉
解决方法: 在给单例类的context赋值的时候最好用赋值
context.getApplicationContext()
3. 非静态内部类造成的内存泄露
这部分包括常说的Handler, 超时Thread, 超时匿名内部类, 等内部类, 标题1中的volley就是其中一种
4. 资源未正常关闭
注册的广播需要在应用退出的时候unregister, 文件流需要close()等
5. final Context生命周期比Activity长
在方法内访问服务器并处理回掉, 如果回掉的内部类使用到context, 需要将该context标记为final, 那么当Activity结束的时候, 如果网络未返回那么该context不会释放, 若该context是Activity的实例, 则引起Activity泄露, 正确的做法是使用context.getApplicationContext去传入网络回掉中.