2

I have a memory leak because of AppCompatTextView It has no click listeners it's just a plain TexView with some text in it.

Is there anything I can do about that? Is that a bug or am I doing something wrong?

enter image description here

I've tried solution suggested here but that didn't helped.

Martynas Jurkus
  • 9,231
  • 13
  • 59
  • 101
  • `InputMethodManager` leaks like a sieve. That being said, if this `AppCompatTextView` happens to be in retained fragment, try making the fragment not be retained. I had an app that provided a similar leak with LeakCanary (though from a `ListView`, not an `AppCompatTextView`). The `ListView` in question was in a page of a `ViewPager`, where the page was a retained fragment. I removed `setRetainInstance(true)` (as part of other code cleanup), and the reported leak went away. – CommonsWare Feb 23 '16 at 13:54
  • Fragment is not retained. But said `TextView` is in a `Fragment` > `ListView` > `HeaderView` – Martynas Jurkus Feb 23 '16 at 14:00

2 Answers2

2

It's an android framework bug. https://code.google.com/p/android/issues/detail?id=34731 It hasn't been fixed yet, even in support library.

Here is the fix:

public static void fixInputMethodManagerLeak(Context destContext) {
    if (destContext == null) {
        return;
    }

    InputMethodManager imm = (InputMethodManager) destContext.getSystemService(Context.INPUT_METHOD_SERVICE);
    if (imm == null) {
        return;
    }

    String[] arr = new String[]{"mCurRootView", "mServedView", "mNextServedView"};
    Field f = null;
    Object obj_get = null;
    for (int i = 0; i < arr.length; i++) {
        String param = arr[i];
        try {
            f = imm.getClass().getDeclaredField(param);
            if (!f.isAccessible()) {
                f.setAccessible(true);
            }
            obj_get = f.get(imm);
            if (obj_get != null && obj_get instanceof View) {
                View v_get = (View) obj_get;
                if (v_get.getContext() == destContext) {  // referenced context is held InputMethodManager want to destroy targets
                    f.set(imm, null);  // set empty, destroyed node path to gc
                } else {
                    // Not want to destroy the target, that is, again into another interface, do not deal with, to avoid affecting the original logic, there is nothing further for the cycle
                    Log.e(TAG, "fixInputMethodManagerLeak break, context is not suitable, get_context=" + v_get.getContext() + " dest_context=" + destContext);
                    break;
                }
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

Call it like this:

@Override
protected void onDestroy() {
    super.onDestroy();
    //if you get memory leak on configuration change too, remove the if clause.
    if (isFinishing()) {
        fixInputMethodManagerLeak(this);
    }
}

Take a look at this question too.

Community
  • 1
  • 1
M. Reza Nasirloo
  • 16,434
  • 2
  • 29
  • 41
0

According to this link: https://code.google.com/p/android/issues/detail?id=179272 It seems that the leak is caused by:

It happens with anything which uses TextLine (TextView, descendants, Layout) with Spanned text. As SearchView uses a SpannableStringBuilder internally, it gets leaked.

I hope it will help you :)

Alexis Clarembeau
  • 2,776
  • 14
  • 27