我有一个执行一些后台任务的AsyncTaskLoader。执行此任务时,需要访问某些视图。 (不,我不能事先获得视图的值 - 它们是自定义视图,附加了一些神奇的东西 - 请接受这个)
但是,这会导致上下文泄漏,因为AsyncTaskLoader持有对Context对象的引用。
问题1)上下文泄漏是不是很糟糕? (我的装载机仅运行100ms - 200ms)
问题2)有没有办法在没有上下文泄漏的情况下保持视图(我很确定不是这样只是一厢情愿的想法)
这不是那么糟糕,对吧?就像旧的观点在几分之一秒之后收集了垃圾。这是唯一的副作用,对吗?
对于记录,我需要引用的视图是来自https://github.com/ArthurHub/Android-Image-Cropper的CropImageView
,我需要在Loader中调用的方法是view.getCroppedImage(width, height, CropImageView.RequestSizeOptions.RESIZE_INSIDE);
(不,因为原因我无法使用预先打包的异步版本的getCroppedImage)
答案 0 :(得分:4)
是,即使是轻微的泄漏也是危险的,因为您永远不知道它可能会泄漏多少内存。在您的示例中,当任何后台任务持有对context
的引用时,它不会允许context
进行垃圾回收,从而留下浪费的内存。这适用于小型物体,但像context, Bitmaps
这样的巨型物体可以容纳大量内存,而不会让GC收集它们。
假设您从Loader
开始Activity A
,
A -> x memory ( x ~ very large memory comparatively )
尽管如此,loader
正在进行中,您更改了移动设备的方向,从而创建了具有相同内存量x的新Activity A
实例。理想情况下,Activity A
的旧实例应该是垃圾收集的,但GC不能重新收集旧的实例内存,因为它强烈地被称为后台任务。
因此,您需要在执行后台任务时处理泄漏,这可以通过两种方式完成 -
取消loader
摧毁activity
实例(或)将weak reference
context
传递给装载程序。
答案 1 :(得分:0)
是的上下文泄漏很糟糕,我们必须手动避免。AsyncWork
保留对Context
的引用,Context
在任务完成之前无法进行GC:{{{ 1}}内存泄漏。有两种解决方案:
1.尽管使用Context
context
长寿的Application
。
2.将异步任务的生命期限定为它所持有引用的context
的生命:在context
中取消它。