在SoftReferences中,Drawable的延迟加载失败

时间:2010-09-29 03:29:36

标签: android optimization user-interface listview lazy-loading

我有一个包含100个不同图像的列表视图。我的缓存如下所示,

public class ImageCache {
    HashMap<String, SoftReference<Drawable>> myCache;
    ....
    ....
    public void putImage(String key, Drawable d) {
        myCache.put(key, new SoftReference<Drawable>(d));
    }

    public Drawable getImage(String key) {
        Drawable d;
        SoftReference<Drawable> ref = myCache.get(key);

        if(ref != null) {
            //Get drawable from reference
            //Assign drawable to d
        } else {
            //Retrieve image from source and assign to d
            //Put it into the HashMap once again
        }
        return d;
    }
}

我有一个自定义适配器,我通过从缓存中检索drawable来设置ImageView的图标。

public View getView(int position, View convertView, ViewGroup parent) {
    String key = myData.get(position);
    .....
    ImageView iv = (ImageView) findViewById(R.id.my_image);
    iv.setImageDrawable(myCache.getImage(key));
    .....
}

但是当我运行程序时,ListView中的大多数图像会在一段时间后消失,其中一些图像在第一个位置甚至不存在。我用硬引用替换了HashMap。像,

HashMap<String, Drawable> myCache

这段代码可行。我想优化我的代码。任何建议。

2 个答案:

答案 0 :(得分:4)

此代码看起来很破碎:

    if(ref != null) {
        //Get drawable from reference
        //Assign drawable to d
    } else {
        //Retrieve image from source and assign to d
        //Put it into the HashMap once again
    }

如果已放置软参考,您将在第一个条件中结束,不会检测到它,也不会重新加载图像。你需要做更多这样的事情:

    Drawable d = ref != null ? ref.get() : null;
    if (d == null) {
        //Retrieve image from source and assign to d
        //Put it into the HashMap once again
    }
    //Get drawable from reference
    //Assign drawable to d

平台广泛使用弱引用来处理从资源和其他东西加载的drawable的缓存,所以如果你从资源中获取东西,你可以让它为你处理。

答案 1 :(得分:2)

Android中的SoftReference存在已知问题。他们可能会被提前释放,你不能依赖他们 http://groups.google.com/group/android-developers/browse_thread/thread/ebabb0dadf38acc1
要解决这个问题,我必须编写自己的SoftReference实现。