本人日常工作遇到的问题,以作记录
通过反射修复
由于是InputMethodManager中的mNextServedView引用了MainActivity,所以最简单的就是通过java中的反射机制将mNextServedView置空,也就是赋值为null,切断了到MainActivity的引用链,从而使MainActivity进行内存回收。
详细参考链接:http://blog.csdn.net/sodino/article/details/32188809
步骤1:创建下面方法
/**
* 处理InputMethodManager内存泄漏方法
*/
public void fixInputMethodManagerLeak(Context destContext) {
if (destContext == null) {
return;
}
InputMethodManager inputMethodManager = (InputMethodManager) destContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager == null) {
return;
}
String [] viewArray = new String[]{"mCurRootView", "mServedView", "mNextServedView"};
Field filed;
Object filedObject;
for (String view:viewArray) {
try{
filed = inputMethodManager.getClass().getDeclaredField(view);
if (!filed.isAccessible()) {
filed.setAccessible(true);
}
filedObject = filed.get(inputMethodManager);
if (filedObject != null && filedObject instanceof View) {
View fileView = (View) filedObject;
if (fileView.getContext() == destContext) { // 被InputMethodManager持有引用的context是想要目标销毁的
filed.set(inputMethodManager, null); // 置空,破坏掉path to gc节点
} else {
break;// 不是想要目标销毁的,即为又进了另一层界面了,不要处理,避免影响原逻辑,也就不用继续for循环了
}
}
}catch(Throwable t){
t.printStackTrace();
}
}
}
步骤2:在baseActivity的onDestroy方法调用
public class BaseActivity extends AppcompatActivity{
......
@Override
public void onDestroy(){
fixInputMethodManagerLeak(this);
super.onDestroy();
}
}
即可解决.有不正确的地方请指正,十分感谢!
更多解决方法可参考: https://blog.csdn.net/qq402164452/article/details/54378688