匿名类很容易导致内存泄漏,尤其是在 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
原因是,在or中创建匿名类时Fragment
,匿名类将始终包含对Activity
or的隐式引用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;
}
});
}
}
使用数据持有者技术进行重构
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));
}
}