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 (String param : arr) {
try {
f = imm.getClass().getDeclaredField(param);
if (!f.isAccessible()) {
f.setAccessible(true);
}
obj_get = f.get(imm);
if (obj_get instanceof View) {
View v_get = (View) obj_get;
// 被InputMethodManager持有引用的context是想要目标销毁的
if (v_get.getContext() == destContext) {
// 置空,破坏掉path to gc节点
f.set(imm, null);
} else {
// 不是想要目标销毁的,即为又进了另一层界面了,
// 不要处理,避免影响原逻辑,也就不用继续for循环了
break;
}
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
或者
private static Field field;
private static boolean hasField = true;
public static void fixLeak(Context context) {
if (!hasField) {
return;
}
InputMethodManager imm = (InputMethodManager) context.
getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null) {
return;
}
String[] arr = new String[]{"mLastSrvView"};
for (String param : arr) {
try {
if (field == null) {
field = imm.getClass().getDeclaredField(param);
}
if (field == null) {
hasField = false;
}
if (field != null) {
field.setAccessible(true);
field.set(imm, null);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}