匿名类很容易导致内存泄漏,尤其是在Android世界中,由于配置更改,Activity或Fragment可能会突然被破坏.这是许多例子中的一个.
http://chaosinmotion.com/blog/?p=696
http://blog.andresteingress.com/2011/10/12/anonymous-inner-classes-in-android/
https://blogs.oracle.com/olaf/entry/memory_leaks_made_easy
原因是,在Activity或中创建一个匿名类Fragment,匿名类将始终保持对Activityor 的隐式引用Fragment.因此,当Activity由于配置更改而趋于过时时,如果匿名类被外部世界暴露和保留,则无法进行垃圾回收.
那么,我想知道,是否使用数据持有技术是一种好方法,可以完全消除匿名类,以减少内存泄漏的风险?或者,我是偏执狂吗?
public class HomeMenuFragment {
private Parcelable selectedInfo = null;
private List<View> homeMenuRows = new ArrayList<View>();
private void fun() {
...
...
row.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// homeMenuRows is member variable
for (View r : homeMenuRows) {
r.setSelected(false);
}
row.setSelected(true);
// selectedInfo is member variable
selectedInfo = watchlistInfo;
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
public class HomeMenuFragment {
private static class Holder {
public Parcelable selectedInfo = null;
public final List<View> homeMenuRows = new ArrayList<View>();
}
private final Holder holder = new Holder();
private static class MyOnClickLisnter implements OnClickListener {
private final Holder holder;
private final LinearLayout row;
private final WatchlistInfo watchlistInfo;
public MyOnClickLisnter(Holder holder, LinearLayout row, WatchlistInfo watchlistInfo) {
this.holder = holder;
this.row = row;
this.watchlistInfo = watchlistInfo;
}
@Override
public void onClick(View arg0) {
for (View r : holder.homeMenuRows) {
r.setSelected(false);
}
row.setSelected(true);
holder.selectedInfo = watchlistInfo;
}
}
private void fun() {
...
...
row.setOnClickListener(new MyOnClickLisnter(holder, row, watchlistInfo));
}
}
Run Code Online (Sandbox Code Playgroud)
像这样的重构没有帮助.它中的View对象Holder也包含对它的引用Activity,因此如果Holder暴露给外界你有内存泄漏.此外,您的MyOnClickLisnter实例,即使它被声明static,也保持对Holdera和a 的显式引用LinearLayout,两者都持有对的引用Activity.我不是匿名课程的粉丝,但我认为匿名OnClickListener传播的可能性非常小Activity或Fragment非常小.听起来像是你过于偏执.
| 归档时间: |
|
| 查看次数: |
1758 次 |
| 最近记录: |