匿名クラスは、特にAndroidの世界では、構成の変更によりアクティビティまたはフラグメントが突然破壊される可能性があるため、メモリリークを簡単に引き起こす可能性があります。これが多くの例の1つです。
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
、匿名クラスは常にActivity
またはへの暗黙の参照を保持するため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));
}
}