问题
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
回答1:
Yup, you can ignore this leak.
Check for example this issue: https://github.com/square/leakcanary/issues/256
回答2:
/**
* 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();
}
}
}
回答3:
Yes, you can ignore this leak but after all, a leak is an undesirable scenario which we should try to fix using any hack or trick.
An elegant solution for above leak which will work for all versions is here
回答4:
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());
来源:https://stackoverflow.com/questions/34631818/leakcanary-report-leak-in-inputmethodmanager