0

I need help to trace a leak detected with Leak Canary

I have made this class as a part of a library that saves Views as images and leak canary has detected a leak that I'm not sure of how to fix or understand. The leak gets detected in my demo app which contains 1 Activity with a save button. When the button is clicked and I exit the app, the detection happend

enter image description here

1 Answers1

0

Change:

private class AsyncSaveBitmap extends AsyncTask<Void, Void, Void> implements MediaScannerConnection.OnScanCompletedListener

to:

static private class AsyncSaveBitmap extends AsyncTask<Void, Void, Void> implements MediaScannerConnection.OnScanCompletedListener

(i.e., add the static keyword)

This will require some follow-on changes to your onScanCompleted() implementation, which presently relies on the fact that AsyncSaveBitmap is not static, calling your activity's responseListener() method.

As it stands, so long as your task is still running, your activity is leaked, because:

  • You pass your AsyncSaveBitmap to MediaScannerConnection.scanFile() as the callback object

  • The callback object will be held onto by MediaScannerConnection code until the scan is complete

  • The AsyncSaveBitmap class is not static, and so it holds an implicit reference back to the outer Java class, which in this case is your activity

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Making the class static requires me to make a constructor in that class with all parameters that it needs if I want to keep my member variables non static or I could make theese member variables static too. Which approach should I go for? –  May 07 '17 at 15:21
  • @Muddz: "I could make theese member variables static" -- that would make them leaks in their own right. There is a vast difference between a `static` nested class and a `static` field. "Which approach should I go for?" -- pass everything in via the constructor (or setters, if you prefer). – CommonsWare May 07 '17 at 15:26
  • I just completed the changes: https://pastebin.com/1YAtXpeT Have I nailed it with the `AsyncTask` now? So far nothing has been detected by leak canary –  May 07 '17 at 16:19
  • I have noticed that this new way keeps my memory allocated everytime I save a image and increase the memory with about 20 mb for every save till it run out of memory. Before it just hit 47 mb before going down again to 28 mb allocation when saving an image –  May 07 '17 at 16:33
  • @Muddz: "Have I nailed it with the AsyncTask now?" -- I do not see where you are leaking the activity. With regards to your new memory leak, generate a heap dump and see what you are holding onto. – CommonsWare May 07 '17 at 16:37
  • I was thinking... If I made this Async class as class by its own java file, would it be a good idea? –  May 12 '17 at 09:56