2

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.

  • Question 1) Are context leaks that bad? (my loader runs only for 100ms - 200ms)

  • Question 2) Is there a way to hold a view without a context leak (I'm pretty sure not so this is just wishful thinking)

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)

MLavoie
  • 9,671
  • 41
  • 36
  • 56
AlanSTACK
  • 5,525
  • 3
  • 40
  • 99
  • Of course context leaks is bad, you need to avoid it. Use weakreference to hold your context/activity/view when access it from background thread. Check this link(it refer to AsyncTask only but can do the same with AsyncTaskLoader) maybe useful: https://stackoverflow.com/questions/9809336/android-asyntask-use-weak-reference-for-context-to-avoid-device-rotate-screen – Truong Giang Dam Jan 08 '18 at 05:11
  • @TruongGiangDam I'm not really well versed in how the exact implementations of weak references work - but from what I can tell they are just normal references that don't prevent garbage collection. Problem is - I kinda need to use them in the AsyncTaskLoader - I don't want them to get garbage collected and transformed into null or anything... – AlanSTACK Jan 08 '18 at 05:16

2 Answers2

4

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.

Subin Babu
  • 1,515
  • 2
  • 24
  • 50
Rajan Kali
  • 12,627
  • 3
  • 25
  • 37
0

Yes context leaks is bad,we have to avoid it manually.AsyncWork holds the reference to the Context, the Context cannot be GCed until the task is complete: the Context memory leaks. There are two solutions:

1.Use a context that is long-lived, anyway, the Application context.
2.Tie the life of the async task to the life of the context to which it hold a reference: cancel it in onPause().

Hemant Parmar
  • 3,924
  • 7
  • 25
  • 49