/**
* 防止inputMethodManager造成的内存泄漏
* @param destContext
*/
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() == false) {
f.setAccessible(true);
} // author: sodino mail:sodino@qq.com
obj_get = f.get(imm);
if (obj_get != null && obj_get instanceof View) {
View v_get = (View) obj_get;
if (v_get.getContext() == destContext) { // 被InputMethodManager持有引用的context是想要目标销毁的
f.set(imm, null); // 置空,破坏掉path to gc节点
} else {
// 不是想要目标销毁的,即为又进了另一层界面了,不要处理,避免影响原逻辑,也就不用继续for循环了
break;
}
}
}catch(Throwable t){
t.printStackTrace();
}
}
* 防止inputMethodManager造成的内存泄漏
* @param destContext
*/
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() == false) {
f.setAccessible(true);
} // author: sodino mail:sodino@qq.com
obj_get = f.get(imm);
if (obj_get != null && obj_get instanceof View) {
View v_get = (View) obj_get;
if (v_get.getContext() == destContext) { // 被InputMethodManager持有引用的context是想要目标销毁的
f.set(imm, null); // 置空,破坏掉path to gc节点
} else {
// 不是想要目标销毁的,即为又进了另一层界面了,不要处理,避免影响原逻辑,也就不用继续for循环了
break;
}
}
}catch(Throwable t){
t.printStackTrace();
}
}
}
然后在onDestroy()内调用该方法
@Override
protected void onDestroy() {
super.onDestroy();
fixInputMethodManagerLeak(this);
}