在进入android 5.0 Settings应用中进入apps项然后反复的进入某个应用的详细信息页面,
使用adb shell dumpsys meminfo appname查看内存信息,每次进入一次应用详情页面
都会导致内存增加。
要搞清楚这个问题得分析InstalledAppDetails和AppInfoBase的代码,实际上前者继承了
后者。
AppInfoBase继承于SettingsPreferenceFragment,本质上是一个Fragment。
它的onCreate方法如下:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFinishing = false;
mState = ApplicationsState.getInstance(getActivity().getApplication());
mSession = mState.newSession(this);
Context context = getActivity();
......
retrieveAppEntry();
}
这里会调用单例类:ApplicationsState对象的newSession方法将自己作为参数传递。
看下ApplicationState的newSession方法:
public Session newSession(Callbacks callbacks) {
Session s = new Session(callbacks);
synchronized (mEntriesMap) {
mSessions.add(s);
}
return s;
}
下面是Session的构造函数:
Session(Callbacks callbacks) {
mCallbacks = callbacks;
}
Session使用了一个成员变量mCallbacks引用了callbacks即Session引用了AppInfoBase这个Fragment.
同时Session在newSession方法中被加入了ApplicationState类成员变量mSessions中。也就是说ApplicationState
这个类有全局唯一单例类,使用了一个列表保存了每一个AppInfoBase创建的Session,从而间接的持有者每一个
AppInfoBase.如果Session不从mSessions中移除,那么每个AppInfoBase都不会被释放。那么什么时候Session
会从mSessions中移除呢?
Session有个release方法:
public void release() {
pause();
synchronized (mEntriesMap) {
mSessions.remove(this);
}
}
在这个方法里将自己移除掉的。
那AppInfoBase会调用这个方法吗?查看整个AppInfoBase的code没有发现调用此方法。因此每个AppInfoBase及其
子类都不会被释放, 导致内存泄露。
这个问题修改的方法就是在AppInfoBase的onDestory方法中调用Session的release方法。