今年开发的一个项目发生了内存泄漏,在六七月份时就观察到即使退出了所有的activity,但是app在后台占用的内存还是没有降下来,保持到75M左右。一直以为是项目使用的代码出现问题,然后继续优化,可是无论怎么优化都达不到合理的内存占用值,最后挤挤牙膏也是降到了60M那样。当时优化了一周效果并不明显。好在60M对于我们应用来说还能够接受,就继续开发迭代功能。最近其他项目迭代开发完成比较有空了,就回到原来项目区看看还能不能继续优化。由于当时项目用的Android studio2.3作为开发工具所以内存调优工具没有那么好,于是就换到最新的Android studio3.2
Android studio3.2的内存工具是profiler,在Android studio的左下角可以打开
经过两天的debug准确定位了问题
这里就形成了变量循环链
可以看到因为InputMethodManager的生命周期非常长,导致即使activity被onDestroy()后也无法顺利被回收,进而导致更多变量无法回收的内存泄漏。
为此特地Google了一把,发现从Android4.4到Android6.0这个bug一直存在。
解决方案:这个问题在不少人遇到过,已经有成形的代码可以使用,具体代码下面的GitHub
https://gist.github.com/pyricau/4df64341cc978a7de414
当然这份代码有两个地方需要修改
public static void fixFocusedViewLeak(Application application) {
// Don't know about other versions yet.
if (SDK_INT < KITKAT || SDK_INT > 22) {
return;
}
//......
}
修改原因
1. InputMethodManager内存泄漏的bug在Android6.0还存在;
2. SDK_INT > 22使用了魔鬼数字,可以更新最新的SDK将魔鬼数字改为Version代号
修改结果如下:
public static void fixFocusedViewLeak(Application application) {
// Don't know about other versions yet.
if (SDK_INT < Build.VERSION_CODES.KITKAT || SDK_INT > Build.VERSION_CODES.M) {
return;
}
//......
}
以下代码解决了在activity退出后立即将view与InputMethodManager解绑
package com.lucky.utils;
import android.app.Activity;
import android.app.Applicati