9

我正在构建一个 android 应用程序,其中每个实体都有一个表示其精灵的位图。但是,每个实体都可以复制(例如,实体 asdf 可能有 3 个副本)。

一种方法是预先加载所有精灵,然后将正确的精灵放入实体的构造函数中。

但是,我想延迟解码位图,以便实体的构造函数解码位图。唯一的问题是重复的实体将加载相同的位图两次,使用 2 倍的内存(或者如果实体被创建 n 次,则为 n 次)。

为了解决这个问题,我构建了一个 SingularBitmapFactory,它将解码的位图存储到哈希中,如果再次请求相同的位图,将简单地返回先前的哈希位图,而不是构建一个新的位图。但是,问题在于工厂拥有所有位图的副本,因此永远不会被垃圾收集。

将哈希图切换为具有弱引用值的最佳方法是什么?换句话说,我想要一个结构,如果任何其他对象持有对它的引用,则值不会被 GC,但只要没有其他对象引用它,那么它就可以被 GC。

4

3 回答 3

12

你说的差不多 - 使位图(地图的对象侧)成为弱引用而不是位图。然后,您必须添加额外的检查以查看引用是否仍然有效,然后再将其传递回您的实体。以下是总体思路的速写。

public class SingularBitmapFactory { 
    private HashMap <String, WeakReference<Bitmap>> cache = new HashMap<String, WeakReference<Bitmap>>();

    public Bitmap getBitmap(String key) {
        Bitmap image = null;
        WeakReference<Bitmap> ref = cache.get(key);
        if(ref != null) {
            image = ref.get();
        }
        if(image == null) {
            // Load image here ... 
            cache.put(key, new WeakReference<Bitmap>(image));
        }
        return image;   
    }
}
于 2012-12-15T04:58:45.397 回答
7

老问题,但我今天需要这个,根据@iagreen的回答我已经概括了这个想法,也许它对某人有用......

public static class WeakValueHashMap<K,V> {
    private HashMap<K,WeakReference<V>> mDatabase=new HashMap<K, WeakReference<V>>();
    public V get(K key) {
        WeakReference<V> weakRef=mDatabase.get(key);
        if (weakRef==null) return null;
        V result=weakRef.get();
        if (result==null) {
            // edge case where the key exists but the object has been garbage collected
            // we remove the key from the table, because tables are slower the more
            // keys they have (@kisp's comment)
            mDatabase.remove(key);
        }
        return result;
    }
    public void put(K key, V value) {
        mDatabase.put(key, new WeakReference<V>(value));
    }
}

所以你可以做例如

    private WeakValueHashMap<String,Drawable> mTextDrawables=new WeakValueHashMap<String,Drawable>();

并且可绘制对象将与Weakreferences.

“containsValue”方法实现起来会比较棘手,你必须迭代和取消引用所有的 WeakRefs ...

于 2014-09-02T23:48:34.393 回答
-3

最好的方法是使用 Wea​​kHashMap 类,它为您完成所有工作,并且不需要对您的代码进行任何更改。这里有一个非常好的教程:http : //weblogs.java.net/blog/2006/05/04/understanding-weak-references 它相当陈旧但仍然可以。WeakHashMap 存储对键的弱引用很重要。这意味着您不能只使用常量字符串值作为键,而是使用 Integer 之类的东西并将其作为弱引用存储在常量类中。

于 2012-12-15T05:00:12.230 回答