您的位置:首页 > 移动开发

Android Settings app内存泄露问题

2016-04-29 13:58 609 查看
在进入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方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android