2

我正在通过直接从 View 类继承来编写自定义视图,我想知道我是否很好地利用了 WeakReference 类。首先,这是我班上最相关的部分:

public class ChessView extends View {

    public ChessView(Context context, AttributeSet attrs, int defStyle) {
        /* some code removed */
        invalidateHandler = new InvalidateHandler(this);

        new Thread(new Runnable() {

            @Override
            public void run() {
                     invalidateHandler.sendMessage(invalidateHandler.obtainMessage());
        }

        }).start();
    }

    /* some code removed */

    private static class InvalidateHandler extends Handler {

        public InvalidateHandler(ChessView view){
            relatedChessView = new WeakReference<ChessView>(view);
        }

        @Override
        public void handleMessage(Message msg) {
            relatedChessView.get().invalidate();
        }

        private WeakReference<ChessView> relatedChessView; 
    };

    private InvalidateHandler invalidateHandler;

}

如你看到的 :

  1. 我正在创建一个静态内部类,它是 Handler 类的子类:正如 android 开发人员指南建议避免 View 子类中的直接内部类
  2. Handler 静态内部类调用我的自定义 ChessView 的 invalidate() 方法:所以我决定将它“包装”在 WeakReference 中,因为 android 开发人员指南建议避免对 View 实例进行硬引用。

所以这里是我的问题:

  1. 我是否可以通过这种方式避免内存泄漏?
  2. WeakReference 是最好的类型,还是应该使用 SoftReference 代替?
  3. 最后,只要视图可见(或相关活动处于活动状态),自定义视图是否会保留在堆上,或者它可能由 GC 之前收集,让我在调用 relatedChessView.get() 时使用空引用?

提前致谢,如果我的问题表述不当,我们深表歉意。

4

1 回答 1

4

我是否可以通过这种方式避免内存泄漏?

是的,但这不是必需的。

WeakReference 是最好的类型,还是应该使用 SoftReference 代替?

WeakReference在你的情况下是要走的路。只要有硬参考指向它们,它们都将可用SoftReferenceWeakReference但是,如果没有强引用,WeakReference则更有可能被收集,而SoftReference只要不需要清理内存(例如,将保留更长时间),就会保留您的对象SoftReference

最后,只要视图可见(或相关活动处于活动状态),自定义视图是否会保留在堆上,或者它可能由 GC 之前收集,让我在调用 relatedChessView.get() 时使用空引用?

是的,它会。正如我上面提到的,WeakReference当有任何Objects持有包含Object的参考时,将不会被收集。

更新:根据@DeeV 的回答修复了有关弱引用和软引用的信息,使其更加准确。

于 2012-08-10T11:43:20.957 回答