Является ли это хорошей методикой (использование держателя данных) для устранения анонимного класса, чтобы уменьшить риск утечки памяти

Анонимный класс может легко вызвать утечку памяти, особенно в мире Android, где активность или фрагмент могут быть внезапно уничтожены из-за изменений конфигурации. Вот один из многих примеров.

On Memory Leaks in Java and in Android.

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)); } } 

Solutions Collecting From Web of "Является ли это хорошей методикой (использование держателя данных) для устранения анонимного класса, чтобы уменьшить риск утечки памяти"

Рефакторинг подобным образом не помогает. Объекты View в Holder также содержат ссылки на Activity , поэтому, если Holder подвергается воздействию внешнего мира, у вас есть утечка памяти. Кроме того, ваш экземпляр MyOnClickLisnter , даже если он объявлен static , содержит явную ссылку на Holder и LinearLayout , в обоих из которых содержатся ссылки на Activity . Я не поклонник анонимных классов, но я думаю, что вероятность анонимного OnClickListener , передаваемого вне Activity или Fragment , очень мала. Мне кажется, что ты чересчур параноик.