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