这是一种很好的技术(使用数据持有者)来消除匿名类,以减少内存泄漏风险

Che*_*eng 6 java android

匿名类很容易导致内存泄漏,尤其是在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)

Dav*_*ser 5

像这样的重构没有帮助.它中的View对象Holder也包含对它的引用Activity,因此如果Holder暴露给外界你有内存泄漏.此外,您的MyOnClickLisnter实例,即使它被声明static,也保持对Holdera和a 的显式引用LinearLayout,两者都持有对的引用Activity.我不是匿名课程的粉丝,但我认为匿名OnClickListener传播的可能性非常小ActivityFragment非常小.听起来像是你过于偏执.