8

I am trying to figure it out a leak in my app but I am not sure were this comes from.

LeakCanary is telling me that I can ignore it. Is that right?

01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * LEAK CAN BE IGNORED.
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * com.mypackage.ui.map.MapComponentFragment has leaked:
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * GC ROOT android.view.inputmethod.InputMethodManager$1.this$0 (anonymous class extends com.android.internal.view.IInputMethodClient$Stub)
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * references android.view.inputmethod.InputMethodManager.mCurRootView
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * references com.android.internal.policy.impl.PhoneWindow$DecorView.mContext
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * references com.mypackage.ui.MainActivity.mFragments
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * references android.app.FragmentManagerImpl.mAdded
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * references java.util.ArrayList.array
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * references array java.lang.Object[].[0]
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * leaks com.mypackage.ui.map.MapComponentFragment instance
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * Reference Key: 0790f013-1c87-4d5f-8c10-db277187e3ce
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * Device: samsung samsung SM-N910C treltexx
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * Android Version: 5.1.1 API: 22 LeakCanary: 1.4-SNAPSHOT 2714152
01-06 12:04:56.580 6935-9159/com.mypackage D/LeakCanary: * Durations: watch=5085ms, gc=149ms, heap dump=2562ms, analysis=10313ms

There were several leaks caused by this fragment, but I fix them. This one I can't make it disappear.

Any clue?

EDIT

One more thing, if I want to ignore it this should be enough?

.instanceField("android.view.inputmethod.InputMethodManager", "mCurRootView")

But is still showing up in LeakCanary

Apparently this leak is in AndroidExcludeRef but still being reported. https://github.com/square/leakcanary/issues/322

Marcel
  • 2,094
  • 3
  • 23
  • 37
  • There are various solutions or workarounds: https://issuetracker.google.com/issues/37043700#comment17 https://issuetracker.google.com/issues/36950938 https://stackoverflow.com/questions/5038158/main-activity-is-not-garbage-collected – Mr-IDE Jan 14 '18 at 13:08

4 Answers4

4
/**
 * call this method in activity onDestroy() method.
*/
public static void fixInputMethod(Context context) {
    if (context == null) {
        return;
    }
    InputMethodManager inputMethodManager = null;
    try {
        inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    } catch (Throwable th) {
        th.printStackTrace();
    }
    if (inputMethodManager == null) {
        return;
    }
    Field[] declaredFields = inputMethodManager.getClass().getDeclaredFields();
    for (Field declaredField : declaredFields) {
        try {
            if (!declaredField.isAccessible()) {
                declaredField.setAccessible(true);
            }
            Object obj = declaredField.get(inputMethodManager);
            if (obj == null || !(obj instanceof View)) {
                continue;
            }
            View view = (View) obj;
            if (view.getContext() == context) {
                declaredField.set(inputMethodManager, null);
            } else {
                continue;
            }
        } catch (Throwable th) {
            th.printStackTrace();
        }
    }
}
boiledwater
  • 10,372
  • 4
  • 37
  • 38
3

Yup, you can ignore this leak.

Check for example this issue: https://github.com/square/leakcanary/issues/256

Sandro Machado
  • 9,921
  • 4
  • 36
  • 57
  • the weird thing is when I do ignore I get others like this. Always coming from this fragment – Marcel Jan 06 '16 at 12:30
  • It is a bug from the Android framework and probably is already reported (and fixed in the next releases of Android). So you cannot do something about the issue, so you should ignore it. – Sandro Machado Jan 06 '16 at 12:34
  • I understood that, but still feels weird that when I ignore this one I get a new one from a listener in a button... – Marcel Jan 06 '16 at 12:50
  • And that have the TAG `LEAK CAN BE IGNORED.`? – Sandro Machado Jan 06 '16 at 13:49
  • I found the reasons of others but I can't ignore this one. Seams that the PhoneWindows is keeping the reference to the activity even after this one is destroyed. How can avoid getting this leak. (see my update question) – Marcel Jan 06 '16 at 17:24
2

Yes, you can ignore this leak. A hacky solution for solving above leak which will work for all versions is here


EDIT April 2022:-

The Author of medium story deleted it but the solution was around using a transparent activity as an exit activity.

humble_wolf
  • 1,497
  • 19
  • 26
0

LeakCanary is already take this leak as a Android OS fault. But still happening, what it annoyed me. If someone gets into this and wants to fix it, there is a workaround for it.

https://gist.github.com/pyricau/4df64341cc978a7de414

Just call on the onCreate of your Activity this

IMMLeaks.fixFocusedViewLeak(getApplication());
Marcel
  • 2,094
  • 3
  • 23
  • 37