我建立一个Android应用程序,其中每个实体都有代表其精灵的位图。 然而,每一个实体可以被复制(可能有例如实体航空自卫队的3份)。
一种方法是加载所有的精灵前期,然后把正确的精灵在实体的构造函数。
不过,我想对位图解码懒洋洋,从而使实体的构造将解码的位图。 与此唯一的问题是重复的实体将加载相同的位图的两倍,使用2倍的内存(或N倍,如果在创建实体n次)。
为了解决这个问题,我建这将解码位图存储到一个散列SingularBitmapFactory,如果相同的位图被再次请求,将简单地返回,而不是建立一个新的先前散列之一。 带着这样的问题,不过,是该工厂拥有所有的位图的副本,所以永远不会得到收集垃圾。
什么是HashMap中切换到一个与弱引用值的最佳方式是什么? 。换句话说,我想其中如果任何其他对象持有对它的引用,但只要没有其他对象是指它,那么它可以被GC'd的值将不被GC'd的结构。
几乎你说的话 - 使位图(地图对象侧)WeakReference的,而不是一个位图。 然后,你必须添加额外的检查,看是否引用仍然传递回你的实体之前有效。 这里的总体思路的速写。
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;
}
}
老问题,但我需要这样的今天,基于@ 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 ...
最好的办法是使用WeakHashMap中类做所有的工作适合你,也不需要你的代码进行任何更改。 有一个很好的教程在这里: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references其相当老气,但仍好了。 重要的是,在WeakHashMap中存储弱引用的关键。 这意味着你不能只用一个常量字符串值作为重点,而是使用类似的一个整数并将其存储在一个常量类作为弱引用。