android-fragmentsmemory-leaksandroid-widgetcommonsware

Can't find the leak, on my fragment android code


I have a TabLayout, under each tab there is a Fragment (I'm using ArrayPagerAdapter). I've noticed that when I switch many times from a tab to another, my memory usage increase a lot. From my heap snapshot, I can see there are a lot of AutoCompleteTextView instances.

Android's studio memory tool

So I am convinced that the problem could be here:

public class MyFragment  {
...
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    final MultiAutoCompleteTextView eInput = (MultiAutoCompleteTextView) v.findViewById(R.id.TextInput);
    EditorListener mEditorListener = new EditorListener();
    eInput.setOnEditorActionListener(mEditorListener);
    eInput.addTextChangedListener(new WhitespaceWatcher());
    eInput.setAdapter(mDictionaryAdapter);
    eInput.setTokenizer(new SpaceTokenizer());
    ...
  }
...
  class EditorListener implements TextView.OnEditorActionListener
  {
  @Override
  public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
    ...
    MultiAutoCompleteTextView input = (MultiAutoCompleteTextView) textView.findViewById(R.id.TextInput);
    ...
  }
}
...
}

Android Studio's memory tool Reference tree

But I can't understand where exactly the problem is.


Solution

  • Note to others: the poster and I had an off-SO discussion about this issue, and the poster created this sample app that was able to reproduce the problem.


    After some struggling, I was able to get LeakCanary to work. It required 1.4-beta1 versus the shipping 1.3.1. All I needed to do was add the dependencies and set up an Application subclass per the LeakCanary docs. Then, launch the app and press BACK once the activity appears.

    You get:

    LeakCanary Output

    Whether this is a framework bug or something introduced by appcompat-v7 and its specific subclass of MultiAutoCompleteTextView, I can't say at present. However, it is definitely not a bug in your code.

    Clearing the adapter from the MultiAutoCompleteTextView (setAdapter(null)) in onDestroyView() of the fragment should prevent it from leaking the activity, but the widget itself will still leak. A quick scan of the relevant code does not give me much hope that the leak itself can be fixed without modifications to either the framework (for MultiAutoCompleteTextView) or appcompat-v7 (for its subclass).