androidmemory-leaksasynctaskloader

Is "leaking" context inside AsyncTaskLoader that bad?


I have an AsyncTaskLoader that does some background task. While doing this task, it needs to access some views. (No I can't just get the values of the views beforehand - they are custom views, with some magic stuff attached to it - please just accept this)

However, this is causing a context leak because the AsyncTaskLoader is holding a reference to a Context object.

It's not that bad, right? Like the old views are garbage collected a fraction of a second later.- that's the only side effect, right?

For the record the view I need a reference to is CropImageView from https://github.com/ArthurHub/Android-Image-Cropper and the method I need to call from inside the Loader is view.getCroppedImage(width, height, CropImageView.RequestSizeOptions.RESIZE_INSIDE);

(no I can't use the prepackaged async versions of getCroppedImage because of reasons)


Solution

  • Yes, even minor leaks are dangerous because you'll never know how much memory it might leak. In your example, when any of the background tasks is holding the reference to context, it won't allow context to be garbage collected thereby leaving a wasted memory. This is fine for small objects but giant objects like context, Bitmaps holds tons lot of memory without letting it collected by GC.

    Assume, you started a Loader from Activity A,

    A -> x memory ( x ~ very large memory comparatively )
    

    While still, the loaderis in progress you changed the orientation of mobile, which creates a new instance of Activity A with the same amount of memory x. Ideally old instance of Activity A should be garbage collected but GC can't recollect old instance memory as it is Strongly referred to a background task.

    Hence, you need to take care of leaks while performing background tasks, this can be done in two ways -

    either cancel the loader on destroying the activity instance (or) pass weak reference of your context to a loader.